Compare commits

...

233 Commits
4.2.1 ... 5.0.0

204 changed files with 7477 additions and 4559 deletions

13
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: ['https://buy.stripe.com/3cs6rP6YA91sbbG5kk','https://jsd.012700.xyz/gh/jerryc127/CDN/Photo/wechat.jpg'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -7,19 +7,30 @@ body:
attributes: attributes:
value: | value: |
重要:請依照該模板來提交 重要:請依照該模板來提交
Please follow the template to create a new issue Important: Please follow the template to create a new issue
- type: input - type: input
id: butterfly-ver id: butterfly-ver
attributes: attributes:
label: 使用的 Butterfly 版本? | What version of Butterfly are you use? label: 使用的 Butterfly 版本? | What version of Butterfly are you using?
description: 檢視主題的 package.json | Check the theme's package.json description: 檢視主題的 package.json | Check the theme's package.json
validations: validations:
required: true required: true
- type: dropdown
id: modify
attributes:
label: 是否修改過主題文件? | Has the theme files been modified?
options:
- 是 (Yes)
- 否 (No)
validations:
required: true
- type: dropdown - type: dropdown
id: browser id: browser
attributes: attributes:
label: 使用的瀏覽器? || What browse are you using? label: 使用的瀏覽器? | What browser are you using?
options: options:
- Chrome - Chrome
- Edge - Edge
@@ -32,7 +43,7 @@ body:
- type: dropdown - type: dropdown
id: platform id: platform
attributes: attributes:
label: 使用的系統? || What operating system are you using? label: 使用的系統? | What operating system are you using?
options: options:
- Windows - Windows
- macOS - macOS
@@ -43,6 +54,15 @@ body:
validations: validations:
required: true required: true
- type: textarea
id: dependencies
attributes:
label: 依賴插件 | Package dependencies information
description: 在 Hexo 根目錄下執行 `npm ls --depth 0` | Run `npm ls --depth 0` in Hexo root directory
render: Text
validations:
required: true
- type: textarea - type: textarea
id: description id: description
attributes: attributes:
@@ -56,8 +76,8 @@ body:
- type: input - type: input
id: website id: website
attributes: attributes:
label: 出現問題網站 | Website label: 出現問題網站 | Website with the issue
description: 請提供可復現網站地址 | Please supply a website url which can reproduce problem. description: 請提供可復現問題的網站地址 | Please provide a website URL where the problem can be reproduced.
placeholder: placeholder: 請填寫具體的網址,不要填寫 localhost 網站 | Please provide a specific URL, do not use localhost.
validations: validations:
required: true required: true

View File

@@ -12,11 +12,7 @@ contact_links:
url: https://t.me/bu2fly url: https://t.me/bu2fly
about: 'Official Telegram Group' about: 'Official Telegram Group'
- name: QQ 1 - name: QQ 群
url: https://jq.qq.com/?_wv=1027&k=KU9105XR url: https://jq.qq.com/?_wv=1027&k=KU9105XR
about: '群號 1070540070不要兩個Q群都添加' about: '群號 1070540070'
- name: QQ 2群
url: https://jq.qq.com/?_wv=1027&k=r1nK0DQz
about: '群號 978221020不要兩個Q群都添加'

20
.github/stale.yml vendored
View File

@@ -1,20 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 30
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
- bug
- enhancement
- documentation
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

19
.github/workflows/stale.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v5
with:
days-before-issue-stale: 30
days-before-pr-stale: -1
days-before-close: 7
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
close-pr-message: 'This issue has not seen any activity since it was marked stale. Closing.'
stale-issue-label: 'Stale'
exempt-issue-labels: 'pinned,bug,enhancement,documentation,Plan'
operations-per-run: 1000

View File

@@ -1,9 +1,11 @@
<div align="right"> <div align="right">
Language: <a title="Chinese" href="/README_CN.md">中文</a>
🇺🇸
<a title="Chinese" href="/README_CN.md">🇨🇳</a>
</div> </div>
<div align="center">
<img src="./source/img/butterfly-icon.png" width="150" height="150" />
# hexo-theme-butterfly # hexo-theme-butterfly
![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/master?color=%231ab1ad&label=master) ![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/master?color=%231ab1ad&label=master)
@@ -12,13 +14,15 @@
![hexo version](https://img.shields.io/badge/hexo-5.3.0+-0e83c) ![hexo version](https://img.shields.io/badge/hexo-5.3.0+-0e83c)
![license](https://img.shields.io/github/license/jerryc127/hexo-theme-butterfly?color=FF5531) ![license](https://img.shields.io/github/license/jerryc127/hexo-theme-butterfly?color=FF5531)
📢 Demo: [Butterfly](https://butterfly.js.org/) / [CrazyWong](https://blog.crazywong.com/)
📖 Docs: [English](https://butterfly.js.org/en/posts/butterfly-docs-en-get-started/) / [Chinese](https://butterfly.js.org/posts/21cfbf15/)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/theme-butterfly-readme.png) ![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/theme-butterfly-readme.png)
Demo: 👍 [Butterfly](https://butterfly.js.org/) || 🤞 [CrazyWong](https://crazywong.com/) </div>
Docs: 📖 [Butterfly Docs](https://butterfly.js.org/posts/21cfbf15/) ---
Based on [hexo-theme-melody](https://github.com/Molunerfinn/hexo-theme-melody) theme.
## 💻 Installation ## 💻 Installation
@@ -61,27 +65,28 @@ npm i hexo-theme-butterfly
## 🎉 Features ## 🎉 Features
- [x] Card UI Design - [x] Card UI Design
- [x] Rounded Design/Squared Design
- [X] Support sub-menu - [X] Support sub-menu
- [x] Two Column designs - [x] Two-column layout
- [x] Responsive Web Design - [x] Responsive Web Design
- [x] Dark Mode - [x] Dark Mode
- [x] Pjax - [x] Pjax
- [x] Read Mode - [x] Read Mode
- [x] Conversion between Traditional and Simplified Chinese - [x] Conversion between Traditional and Simplified Chinese
- [X] TOC catalog is available for both computers and mobile phones - [X] TOC catalog is available for both computers and mobile phones
- [X] Color themes (darker/pale night/light/ocean/mac/mac light), support custom colors - [X] Built-in Syntax Highlighting Themes (darker/pale night/light/ocean), also support customization
- [X] Code Blocks (Display code language/close or expand Code Blocks/Copy Button/word wrap) - [X] Code Blocks (Display code language/close or expand Code Blocks/Copy Button/word wrap)
- [X] Disable copy/Add a Copyright Notice to the Copied Text - [X] Disable copy/Add a Copyright Notice to the Copied Text
- [X] Search (Algolia SearchZ/Local Search) - [X] Search (Algolia Search/Local Search)
- [x] Mathjax and Katex - [x] Mathjax and Katex
- [x] Built-in 404 page - [x] Built-in 404 page
- [x] WordCount - [x] WordCount
- [x] Related articles - [x] Related articles
- [x] Displays outdated notice for a post - [x] Displays outdated notice for a post
- [x] Share (AddThis/Sharejs/Addtoany) - [x] Share (Sharejs/Addtoany)
- [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus) - [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk)
- [x] Multiple Comment System Support - [x] Multiple Comment System Support
- [x] Online Chats (Chatra/Tidio/Daovoice/Gitter/Crisp) - [x] Online Chats (Chatra/Tidio/Daovoice/Crisp)
- [x] Web analytics - [x] Web analytics
- [x] Google AdSense - [x] Google AdSense
- [x] Webmaster Verification - [x] Webmaster Verification
@@ -89,7 +94,7 @@ npm i hexo-theme-butterfly
- [x] Typewriter Effect: activate_power_mode - [x] Typewriter Effect: activate_power_mode
- [x] Background effects (Canvas ribbon/canvas_ribbon_piao/canvas_nest) - [x] Background effects (Canvas ribbon/canvas_ribbon_piao/canvas_nest)
- [x] Mouse click effects (Fireworks/Heart/Text) - [x] Mouse click effects (Fireworks/Heart/Text)
- [x] Preloader/Loading Animation - [x] Preloader/Loading Animation/pace.js
- [x] Busuanzi visitor counter - [x] Busuanzi visitor counter
- [x] Medium Zoom/Fancybox - [x] Medium Zoom/Fancybox
- [x] Mermaid - [x] Mermaid
@@ -109,5 +114,3 @@ npm i hexo-theme-butterfly
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-2.jpg) ![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-2.jpg)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-3.jpg) ![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-3.jpg)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-4.jpg) ![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-4.jpg)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/theme-butterfly-readme-homepage-1.png)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/theme-butterfly-readme-homepage-2.png)

View File

@@ -1,9 +1,11 @@
<div align="right"> <div align="right">
語言: <a title="English" href="/README.md">English</a>
中文
<a title="English" href="/README.md">英文</a>
</div> </div>
<div align="center">
<img src="./source/img/butterfly-icon.png" width="150" height="150" />
# hexo-theme-butterfly # hexo-theme-butterfly
![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/master?color=%231ab1ad&label=master) ![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/master?color=%231ab1ad&label=master)
@@ -12,13 +14,15 @@
![hexo version](https://img.shields.io/badge/hexo-5.3.0+-0e83c) ![hexo version](https://img.shields.io/badge/hexo-5.3.0+-0e83c)
![license](https://img.shields.io/github/license/jerryc127/hexo-theme-butterfly?color=FF5531) ![license](https://img.shields.io/github/license/jerryc127/hexo-theme-butterfly?color=FF5531)
📢 預覽: [Butterfly](https://butterfly.js.org/) / [CrazyWong](https://blog.crazywong.com/)
📖 文檔: [中文](https://butterfly.js.org/posts/21cfbf15/) / [English](https://butterfly.js.org/en/posts/butterfly-docs-en-get-started/)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/theme-butterfly-readme.png) ![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/theme-butterfly-readme.png)
預覽: 👍 [Butterfly](https://butterfly.js.org/) || 🤞 [CrazyWong](https://crazywong.com/) </div>
文檔: 📖 [Butterfly Docs](https://butterfly.js.org/posts/21cfbf15/) ---
一款基於[hexo-theme-melody](https://github.com/Molunerfinn/hexo-theme-melody)修改的主題
## 💻 安裝 ## 💻 安裝
@@ -61,6 +65,7 @@ theme: butterfly
## 🎉 特色 ## 🎉 特色
- [x] 卡片化設計 - [x] 卡片化設計
- [x] 圓角化設計/直角化設計
- [X] 支持二級目錄 - [X] 支持二級目錄
- [x] 雙欄設計 - [x] 雙欄設計
- [x] 響應式主題 - [x] 響應式主題
@@ -69,7 +74,7 @@ theme: butterfly
- [x] 文章閲讀模式 - [x] 文章閲讀模式
- [x] 簡體和繁體轉換 - [x] 簡體和繁體轉換
- [X] 電腦和手機都可查看TOC目錄 - [X] 電腦和手機都可查看TOC目錄
- [X] 內置多種代碼配色darker/pale night/light/ocean/mac/mac light),可自定義代碼配色 - [X] 內置多種代碼配色darker/pale night/light/ocean可自定義代碼配色
- [X] 代碼塊顯示代碼語言/關閉或展開代碼塊/代碼複製/代碼自動換行 - [X] 代碼塊顯示代碼語言/關閉或展開代碼塊/代碼複製/代碼自動換行
- [X] 可關閉文字複製/可開啟內容複製增加版權信息) - [X] 可關閉文字複製/可開啟內容複製增加版權信息)
- [X] 兩種搜索( Algolia 搜索和本地搜索) - [X] 兩種搜索( Algolia 搜索和本地搜索)
@@ -78,18 +83,18 @@ theme: butterfly
- [x] 顯示字數統計 - [x] 顯示字數統計
- [x] 顯示相關文章 - [x] 顯示相關文章
- [x] 過期文章提醒 - [x] 過期文章提醒
- [x] 多種分享系統(AddThis/Sharejs/Addtoany - [x] 多種分享系統Sharejs/Addtoany
- [X] 多種評論系統Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus - [X] 多種評論系統Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk
- [x] 支持雙評論部署 - [x] 支持雙評論部署
- [x] 多種在線聊天Chatra/Tidio/Daovoice/Gitter/Crisp - [x] 多種在線聊天Chatra/Tidio/Daovoice/Crisp
- [x] 多種分析系統 - [x] 多種分析系統
- [x] 谷歌廣告/手動廣告位置 - [x] 谷歌廣告/手動廣告位置
- [x] 各種站長驗證Google/Bing/Baidu/360/Yandex - [x] 各種站長驗證
- [x] 修改網站配色 - [x] 修改網站配色
- [x] 打字特效 activate_power_mode - [x] 打字特效 activate_power_mode
- [x] 多種背景特效(靜止彩帶/動態彩帶/Canvas Nest - [x] 多種背景特效(靜止彩帶/動態彩帶/Canvas Nest
- [x] 多種鼠標點擊特效(煙花/文字/愛心) - [x] 多種鼠標點擊特效(煙花/文字/愛心)
- [x] 內置一種 Preloader 加載動畫 - [x] 內置一種 Preloader 加載動畫和 pace.js 加載動畫條
- [x] 不蒜子訪問統計 - [x] 不蒜子訪問統計
- [x] 兩種大圖模式Medium Zoom/Fancybox - [x] 兩種大圖模式Medium Zoom/Fancybox
- [x] Mermaid 圖表顯示 - [x] Mermaid 圖表顯示
@@ -97,7 +102,7 @@ theme: butterfly
- [x] 圖片懶加載 - [x] 圖片懶加載
- [x] Instantpage/Pangu/Snackbar彈窗/PWA...... - [x] Instantpage/Pangu/Snackbar彈窗/PWA......
## ✨ 贡献 ## ✨ 貢獻
<a href="https://github.com/jerryc127/hexo-theme-butterfly/graphs/contributors"> <a href="https://github.com/jerryc127/hexo-theme-butterfly/graphs/contributors">
<img src="https://contrib.rocks/image?repo=jerryc127/hexo-theme-butterfly" /> <img src="https://contrib.rocks/image?repo=jerryc127/hexo-theme-butterfly" />
@@ -109,5 +114,3 @@ theme: butterfly
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-2.jpg) ![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-2.jpg)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-3.jpg) ![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-3.jpg)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-4.jpg) ![](https://cdn.jsdelivr.net/gh/jerryc127/CDN@m2/img/butterfly-readme-screenshots-4.jpg)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/theme-butterfly-readme-homepage-1.png)
![](https://cdn.jsdelivr.net/gh/jerryc127/CDN/img/theme-butterfly-readme-homepage-2.png)

File diff suppressed because it is too large Load Diff

View File

@@ -3,54 +3,52 @@ footer:
theme: Theme theme: Theme
copy: copy:
success: Copy successfully success: Copy Successful
error: Copy error error: Copy Failed
noSupport: The browser does not support noSupport: Browser Not Supported
page: page:
articles: Articles articles: All Articles
tag: Tag tag: Tag
category: Category category: Category
archives: Archives archives: Archives
card_post_count: comments card_post_count: comments
sticky: Sticky no_title: Untitled
no_title: No title
post: post:
created: Created created: Created
updated: Updated updated: Updated
wordcount: Word count wordcount: Word Count
min2read: Reading time min2read: Reading Time
min2read_unit: min min2read_unit: mins
page_pv: Post View page_pv: Post Views
comments: Comments comments: Comments
copyright: copyright:
author: Author author: Author
link: Link link: Link
copyright_notice: Copyright Notice copyright_notice: Copyright Notice
copyright_content: 'All articles in this blog are licensed under <a href="%s">%s</a> unless stating additionally.' copyright_content: 'All articles on this blog are licensed under <a href="%s">%s</a> unless otherwise stated.'
recommend: Related Articles recommend: Related Articles
edit: Edited on edit: Edit
search: search:
title: Search title: Search
load_data: Loading the Database load_data: Loading Database
input_placeholder: Search for Posts
algolia_search: algolia_search:
input_placeholder: Search for Posts hits_empty: 'No results found for: ${query}'
hits_empty: "We didn't find any results for the search: ${query}."
hits_stats: '${hits} results found in ${time} ms' hits_stats: '${hits} results found in ${time} ms'
local_search: local_search:
input_placeholder: Search for Posts hits_empty: 'No results found for: ${query}'
hits_empty: "We didn't find any results for the search: ${query}" hits_stats: '${hits} articles found'
pagination: pagination:
prev: Previous Post prev: Previous
next: Next Post next: Next
comment: Comment comment: Comments
aside: aside:
articles: Articles articles: Articles
@@ -60,62 +58,64 @@ aside:
card_categories: Categories card_categories: Categories
card_tags: Tags card_tags: Tags
card_archives: Archives card_archives: Archives
card_recent_post: Recent Post card_recent_post: Recent Posts
card_webinfo: card_webinfo:
headline: Info headline: Website Info
article_name: Article article_name: Article Count
runtime: runtime:
name: Runtime name: Runtime
unit: days unit: days
last_push_date: last_push_date:
name: Last Push name: Last Update
site_wordcount: Total Count site_wordcount: Total Word Count
site_uv_name: UV site_uv_name: Unique Visitors
site_pv_name: PV site_pv_name: Page Views
more_button: More more_button: View More
card_newest_comments: card_newest_comments:
headline: Newest Comments headline: Latest Comments
loading_text: loading... loading_text: Loading...
error: Unable to get the data, please make sure the settings are correct. error: Unable to retrieve comments, please check the configuration
zero: No Comment zero: No comments
image: image image: Image
link: link link: Link
code: code code: Code
card_toc: Catalog card_toc: Contents
card_post_series: Post Series
date_suffix: date_suffix:
just: Just just: Just now
min: minutes ago min: minutes ago
hour: hours ago hour: hours ago
day: days ago day: days ago
month: months ago month: months ago
donate: Donate donate: Sponsor
share: Share share: Share
rightside: rightside:
readmode_title: Read Mode readmode_title: Reading Mode
translate_title: Toggle Between Traditional Chinese And Simplified Chinese translate_title: Toggle Between Traditional and Simplified Chinese
night_mode_title: Toggle Between Light And Dark Mode night_mode_title: Toggle Between Light and Dark Mode
back_to_top: Back To Top back_to_top: Back to Top
toc: Table Of Contents toc: Table of Contents
scroll_to_comment: Scroll To Comments scroll_to_comment: Scroll to Comments
setting: Setting setting: Settings
aside: Toggle between single-column and double-column aside: Toggle Between Single-column and Double-column
chat: Chat chat: Chat
copy_copyright: copy_copyright:
author: Author author: Author
link: Link link: Link
source: Source source: Source
info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source. info: Copyright belongs to the author. For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source.
Snackbar: Snackbar:
chs_to_cht: Traditional Chinese Activated Manually chs_to_cht: You have switched to Traditional Chinese
cht_to_chs: Simplified Chinese Activated Manually cht_to_chs: You have switched to Simplified Chinese
day_to_night: Dark Mode Activated Manually day_to_night: You have switched to Dark Mode
night_to_day: Light Mode Activated Manually night_to_day: You have switched to Light Mode
loading: Loading... loading: Loading...
load_more: Load More
error404: Page not found error404: Page Not Found

View File

@@ -3,54 +3,52 @@ footer:
theme: Theme theme: Theme
copy: copy:
success: Copy successfully success: Copy Successful
error: Copy error error: Copy Failed
noSupport: The browser does not support noSupport: Browser Not Supported
page: page:
articles: Articles articles: All Articles
tag: Tag tag: Tag
category: Category category: Category
archives: Archives archives: Archives
card_post_count: comments card_post_count: comments
sticky: Sticky no_title: Untitled
no_title: No title
post: post:
created: Created created: Created
updated: Updated updated: Updated
wordcount: Word count wordcount: Word Count
min2read: Reading time min2read: Reading Time
min2read_unit: min min2read_unit: mins
page_pv: Post View page_pv: Post Views
comments: Comments comments: Comments
copyright: copyright:
author: Author author: Author
link: Link link: Link
copyright_notice: Copyright Notice copyright_notice: Copyright Notice
copyright_content: 'All articles in this blog are licensed under <a href="%s">%s</a> unless stating additionally.' copyright_content: 'All articles on this blog are licensed under <a href="%s">%s</a> unless otherwise stated.'
recommend: Related Articles recommend: Related Articles
edit: Edited on edit: Edit
search: search:
title: Search title: Search
load_data: Loading the Database load_data: Loading Database
input_placeholder: Search for Posts
algolia_search: algolia_search:
input_placeholder: Search for Posts hits_empty: 'No results found for: ${query}'
hits_empty: "We didn't find any results for the search: ${query}."
hits_stats: '${hits} results found in ${time} ms' hits_stats: '${hits} results found in ${time} ms'
local_search: local_search:
input_placeholder: Search for Posts hits_empty: 'No results found for: ${query}'
hits_empty: "We didn't find any results for the search: ${query}" hits_stats: '${hits} articles found'
pagination: pagination:
prev: Previous Post prev: Previous
next: Next Post next: Next
comment: Comment comment: Comments
aside: aside:
articles: Articles articles: Articles
@@ -60,62 +58,64 @@ aside:
card_categories: Categories card_categories: Categories
card_tags: Tags card_tags: Tags
card_archives: Archives card_archives: Archives
card_recent_post: Recent Post card_recent_post: Recent Posts
card_webinfo: card_webinfo:
headline: Info headline: Website Info
article_name: Article article_name: Article Count
runtime: runtime:
name: Runtime name: Runtime
unit: days unit: days
last_push_date: last_push_date:
name: Last Push name: Last Update
site_wordcount: Total Count site_wordcount: Total Word Count
site_uv_name: UV site_uv_name: Unique Visitors
site_pv_name: PV site_pv_name: Page Views
more_button: More more_button: View More
card_newest_comments: card_newest_comments:
headline: Newest Comments headline: Latest Comments
loading_text: loading... loading_text: Loading...
error: Unable to get the data, please make sure the settings are correct. error: Unable to retrieve comments, please check the configuration
zero: No Comment zero: No comments
image: image image: Image
link: link link: Link
code: code code: Code
card_toc: Catalog card_toc: Contents
card_post_series: Post Series
date_suffix: date_suffix:
just: Just just: Just now
min: minutes ago min: minutes ago
hour: hours ago hour: hours ago
day: days ago day: days ago
month: months ago month: months ago
donate: Donate donate: Sponsor
share: Share share: Share
rightside: rightside:
readmode_title: Read Mode readmode_title: Reading Mode
translate_title: Switch Between Traditional Chinese And Simplified Chinese translate_title: Toggle Between Traditional and Simplified Chinese
night_mode_title: Switch Between Light And Dark Mode night_mode_title: Toggle Between Light and Dark Mode
back_to_top: Back To Top back_to_top: Back to Top
toc: Table Of Contents toc: Table of Contents
scroll_to_comment: Scroll To Comments scroll_to_comment: Scroll to Comments
setting: Setting setting: Settings
aside: Toggle between single-column and double-column aside: Toggle Between Single-column and Double-column
chat: Chat chat: Chat
copy_copyright: copy_copyright:
author: Author author: Author
link: Link link: Link
source: Source source: Source
info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source. info: Copyright belongs to the author. For commercial use, please contact the author for authorization. For non-commercial use, please indicate the source.
Snackbar: Snackbar:
chs_to_cht: Traditional Chinese Activated Manually chs_to_cht: You have switched to Traditional Chinese
cht_to_chs: Simplified Chinese Activated Manually cht_to_chs: You have switched to Simplified Chinese
day_to_night: Dark Mode Activated Manually day_to_night: You have switched to Dark Mode
night_to_day: Light Mode Activated Manually night_to_day: You have switched to Light Mode
loading: Loading... loading: Loading...
load_more: Load More
error404: Page not found error404: Page Not Found

121
languages/ja.yml Normal file
View File

@@ -0,0 +1,121 @@
footer:
framework: フレームワーク
theme: テーマ
copy:
success: コピー成功
error: コピー失敗
noSupport: ブラウザが対応していません
page:
articles: 記事一覧
tag: タグ
category: カテゴリ
archives: アーカイブ
card_post_count: コメント数
no_title: タイトルなし
post:
created: 作成日
updated: 更新日
wordcount: 総文字数
min2read: 読む時間
min2read_unit:
page_pv: 閲覧数
comments: コメント数
copyright:
author: 著者
link: リンク
copyright_notice: 著作権表示
copyright_content: 'このブログのすべての記事は、<a href="%s">%s</a> ライセンスの下で提供されており、特に明記されていない限り、すべての権利を留保します。転載時には出典を明記してください: <a href="%s">%s</a>。'
recommend: 関連記事
edit: 編集
search:
title: 検索
load_data: データベースを読み込んでいます
input_placeholder: 記事を検索
algolia_search:
hits_empty: '${query} の検索結果が見つかりませんでした。'
hits_stats: '${hits} 件の結果が ${time}ms で見つかりました'
local_search:
hits_empty: '${query} の検索結果が見つかりませんでした。'
hits_stats: '${hits} 件の記事が見つかりました'
pagination:
prev: 前へ
next: 次へ
comment: コメント
aside:
articles: 記事
tags: タグ
categories: カテゴリ
card_announcement: お知らせ
card_categories: カテゴリ
card_tags: タグ
card_archives: アーカイブ
card_recent_post: 最近の記事
card_webinfo:
headline: サイト情報
article_name: 記事数
runtime:
name: 稼働時間
unit:
last_push_date:
name: 最終更新日
site_wordcount: 総文字数
site_uv_name: ユーザー数
site_pv_name: ページビュー数
more_button: もっと見る
card_newest_comments:
headline: 最新コメント
loading_text: ローディング中...
error: コメントを取得できませんでした。設定を確認してください。
zero: コメントがありません
image: 画像
link: リンク
code: コード
card_toc: 目次
card_post_series: シリーズ記事
date_suffix:
just: たった今
min: 分前
hour: 時間前
day: 日前
month: ヶ月前
donate: 寄付
share: 共有
rightside:
readmode_title: 読書モード
translate_title: 簡体字と繁体字の切り替え
night_mode_title: ライトモード/ダークモード切り替え
back_to_top: トップに戻る
toc: 目次
scroll_to_comment: コメントへ移動
setting: 設定
aside: シングルカラムとダブルカラムの切り替え
chat: チャット
copy_copyright:
author: 著者
link: リンク
source: ソース
info: 著作権は著者に帰属します。商業的利用の場合は著者に連絡して許可を得てください。非商業的利用の場合は出典を明記してください。
Snackbar:
chs_to_cht: 繁体字に切り替えました
cht_to_chs: 簡体字に切り替えました
day_to_night: ダークモードに切り替えました
night_to_day: ライトモードに切り替えました
loading: ローディング中...
load_more: もっと見る
error404: ページが見つかりません

121
languages/ko.yml Normal file
View File

@@ -0,0 +1,121 @@
footer:
framework: 프레임워크
theme: 테마
copy:
success: 복사 성공
error: 복사 실패
noSupport: 브라우저가 지원되지 않음
page:
articles: 모든 글
tag: 태그
category: 카테고리
archives: 아카이브
card_post_count: 댓글 수
no_title: 제목 없음
post:
created: 작성일
updated: 수정일
wordcount: 총 글자 수
min2read: 읽기 시간
min2read_unit:
page_pv: 조회수
comments: 댓글
copyright:
author: 작성자
link: 링크
copyright_notice: 저작권 고지
copyright_content: '이 블로그의 모든 글은 <a href="%s">%s</a> 라이선스를 따르며, 별도로 명시되지 않는 한 모든 권리를 보유합니다. 재배포 시 출처를 명시해 주세요: <a href="%s">%s</a>.'
recommend: 관련 글
edit: 편집
search:
title: 검색
load_data: 데이터베이스 로드 중
input_placeholder: 글 검색
algolia_search:
hits_empty: '${query}에 대한 결과를 찾을 수 없습니다.'
hits_stats: '${hits}개의 결과를 ${time}ms 만에 찾음'
local_search:
hits_empty: '${query}에 대한 결과를 찾을 수 없습니다.'
hits_stats: '${hits}개의 글을 찾음'
pagination:
prev: 이전
next: 다음
comment: 댓글
aside:
articles:
tags: 태그
categories: 카테고리
card_announcement: 공지
card_categories: 카테고리
card_tags: 태그
card_archives: 아카이브
card_recent_post: 최근 글
card_webinfo:
headline: 사이트 정보
article_name: 글 수
runtime:
name: 운영 시간
unit:
last_push_date:
name: 마지막 업데이트
site_wordcount: 총 글자 수
site_uv_name: 방문자 수
site_pv_name: 총 조회수
more_button: 더 보기
card_newest_comments:
headline: 최신 댓글
loading_text: 로딩 중...
error: 댓글을 가져올 수 없습니다. 설정을 확인해 주세요.
zero: 댓글 없음
image: 이미지
link: 링크
code: 코드
card_toc: 목차
card_post_series: 시리즈 글
date_suffix:
just: 방금
min: 분 전
hour: 시간 전
day: 일 전
month: 달 전
donate: 후원
share: 공유
rightside:
readmode_title: 읽기 모드
translate_title: 번체와 간체 전환
night_mode_title: 라이트/다크 모드 전환
back_to_top: 맨 위로
toc: 목차
scroll_to_comment: 댓글로 이동
setting: 설정
aside: 단일/이중 열 전환
chat: 채팅
copy_copyright:
author: 작성자
link: 링크
source: 출처
info: 저작권은 작성자에게 있습니다. 상업적 사용을 위해서는 작성자의 허가를 받아야 하며, 비상업적 사용 시에는 출처를 명시해 주세요.
Snackbar:
chs_to_cht: 번체로 전환되었습니다.
cht_to_chs: 간체로 전환되었습니다.
day_to_night: 다크 모드로 전환되었습니다.
night_to_day: 라이트 모드로 전환되었습니다.
loading: 로딩 중...
load_more: 더 보기
error404: 페이지를 찾을 수 없습니다.

View File

@@ -4,48 +4,46 @@ footer:
copy: copy:
success: 复制成功 success: 复制成功
error: 复制错误 error: 复制失败
noSupport: 浏览器不支持 noSupport: 浏览器不支持
page: page:
articles: 文章总览 articles: 全部文章
tag: 标签 tag: 标签
category: 分类 category: 分类
archives: 归档 archives: 归档
card_post_count: 条评论 card_post_count: 条评论
sticky: 置顶 no_title: 无标题
no_title: 无题
post: post:
created: 发表于 created: 发表于
updated: 更新于 updated: 更新于
wordcount: 字数总计 wordcount: 字数
min2read: 阅读时长 min2read: 阅读时长
min2read_unit: 分钟 min2read_unit: 分钟
page_pv: 阅读 page_pv: 浏览
comments: 评论数 comments: 评论数
copyright: copyright:
author: 文章作者 author: 文章作者
link: 文章链接 link: 文章链接
copyright_notice: 版权声明 copyright_notice: 版权声明
copyright_content: '本博客所有文章除特别声明外,均采用 copyright_content: '本博客所有文章除特别声明外,均采用
<a href="%s" target="_blank">%s</a> 许可协议。转载请注明来 <a href="%s" target="_blank">%s</a>' <a href="%s" target="_blank">%s</a> 许可协议。转载请注明来 <a href="%s" target="_blank">%s</a>'
recommend: 相关推荐 recommend: 相关推荐
edit: 编辑 edit: 编辑
search: search:
title: 搜索 title: 搜索
load_data: 数据加载中 load_data: 数据加载中
input_placeholder: 搜索文章
algolia_search: algolia_search:
input_placeholder: 搜索文章 hits_empty: '未找到符合您查询的内容:${query}'
hits_empty: '找不到您查询的内容:${query}' hits_stats: '找到 ${hits} 条结果,耗时 ${time} 毫秒'
hits_stats: '找到 ${hits} 条结果,用时 ${time} 毫秒'
local_search: local_search:
input_placeholder: 搜索文章 hits_empty: '未找到符合您查询的内容:${query}'
hits_empty: '找不到您查询的内容:${query}' hits_stats: '共找到 ${hits} 篇文章'
pagination: pagination:
prev: 上一篇 prev: 上一篇
@@ -63,26 +61,27 @@ aside:
card_archives: 归档 card_archives: 归档
card_recent_post: 最新文章 card_recent_post: 最新文章
card_webinfo: card_webinfo:
headline: 网站资讯 headline: 网站信息
article_name: 文章数目 article_name: 文章数目
runtime: runtime:
name: 运行时间 name: 运行时间
unit: unit:
last_push_date: last_push_date:
name: 最后更新时间 name: 最后更新时间
site_wordcount: 本站总字数 site_wordcount: 本站总字数
site_uv_name: 本站访客数 site_uv_name: 本站访客数
site_pv_name: 本站总访问 site_pv_name: 本站总浏览
more_button: 查看更多 more_button: 查看更多
card_newest_comments: card_newest_comments:
headline: 最新评论 headline: 最新评论
loading_text: 正在加载中... loading_text: 加载中...
error: 无法获取评论,请确认相关配置是否正确 error: 无法获取评论,请确认相关配置是否正确
zero: 没有评论 zero: 暂无评论
image: 图片 image: 图片
link: 链接 link: 链接
code: 代码 code: 代码
card_toc: 目录 card_toc: 目录
card_post_series: 系列文章
date_suffix: date_suffix:
just: 刚刚 just: 刚刚
@@ -91,16 +90,16 @@ date_suffix:
day: 天前 day: 天前
month: 个月前 month: 个月前
donate: 打赏 donate: 赞助
share: 分享 share: 分享
rightside: rightside:
readmode_title: 阅读模式 readmode_title: 阅读模式
translate_title: 简繁转换 translate_title: 简繁转换
night_mode_title: 浅色和深色模式 night_mode_title: 日间和夜间模式
back_to_top: 回到顶部 back_to_top: 回到顶部
toc: 目录 toc: 目录
scroll_to_comment: 直达评论 scroll_to_comment: 前往评论
setting: 设置 setting: 设置
aside: 单栏和双栏切换 aside: 单栏和双栏切换
chat: 聊天 chat: 聊天
@@ -112,11 +111,12 @@ copy_copyright:
info: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 info: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Snackbar: Snackbar:
chs_to_cht: 已切换为繁体 chs_to_cht: 已切换为繁体中文
cht_to_chs: 已切换为简体 cht_to_chs: 已切换为简体中文
day_to_night: 已切换为深色模式 day_to_night: 已切换为深色模式
night_to_day: 已切换为浅色模式 night_to_day: 已切换为浅色模式
loading: 加载中... loading: 加载中...
load_more: 加载更多
error404: 页面没有找到 error404: 页面找到

121
languages/zh-HK.yml Normal file
View File

@@ -0,0 +1,121 @@
footer:
framework: 框架
theme: 主題
copy:
success: 複製成功
error: 複製失敗
noSupport: 瀏覽器不支援
page:
articles: 全部文章
tag: 標籤
category: 分類
archives: 歸檔
card_post_count: 條評論
no_title: 無標題
post:
created: 發表於
updated: 更新於
wordcount: 字數統計
min2read: 閱讀時間
min2read_unit: 分鐘
page_pv: 瀏覽量
comments: 評論數
copyright:
author: 文章作者
link: 文章連結
copyright_notice: 版權聲明
copyright_content: '除特別聲明外,本博客所有文章均採用<a href="%s">%s</a> 授權協議。轉載請註明出處:<a href="%s">%s</a>。'
recommend: 相關文章
edit: 編輯
search:
title: 搜尋
load_data: 正在加載數據庫
input_placeholder: 搜尋文章
algolia_search:
hits_empty: '未找到相關內容:${query}'
hits_stats: '找到 ${hits} 條結果,耗時 ${time} 毫秒'
local_search:
hits_empty: '未找到相關內容:${query}'
hits_stats: '找到 ${hits} 篇文章'
pagination:
prev: 上一頁
next: 下一頁
comment: 評論
aside:
articles: 文章
tags: 標籤
categories: 分類
card_announcement: 公告
card_categories: 分類
card_tags: 標籤
card_archives: 歸檔
card_recent_post: 最新文章
card_webinfo:
headline: 網站資訊
article_name: 文章數目
runtime:
name: 運行時間
unit:
last_push_date:
name: 最後更新時間
site_wordcount: 總字數
site_uv_name: 訪客數
site_pv_name: 總瀏覽量
more_button: 查看更多
card_newest_comments:
headline: 最新評論
loading_text: 正在加載...
error: 無法取得評論,請確認配置是否正確
zero: 暫無評論
image: 圖片
link: 連結
code: 代碼
card_toc: 目錄
card_post_series: 系列文章
date_suffix:
just: 剛剛
min: 分鐘前
hour: 小時前
day: 天前
month: 個月前
donate: 贊助
share: 分享
rightside:
readmode_title: 閱讀模式
translate_title: 簡繁轉換
night_mode_title: 切換日夜模式
back_to_top: 回到頂部
toc: 目錄
scroll_to_comment: 前往評論
setting: 設定
aside: 單欄與雙欄切換
chat: 聊天
copy_copyright:
author: 作者
link: 連結
source: 來源
info: 版權屬於作者所有。商業用途請聯絡作者獲得授權,非商業用途請註明出處。
Snackbar:
chs_to_cht: 已切換為繁體中文
cht_to_chs: 已切換為簡體中文
day_to_night: 已切換為深色模式
night_to_day: 已切換為淺色模式
loading: 正在加載...
load_more: 加載更多
error404: 未找到頁面

View File

@@ -4,48 +4,45 @@ footer:
copy: copy:
success: 複製成功 success: 複製成功
error: 複製錯誤 error: 複製失敗
noSupport: 瀏覽器不支援 noSupport: 瀏覽器不支援
page: page:
articles: 文章總覽 articles: 所有文章
tag: 標籤 tag: 標籤
category: 分類 category: 分類
archives: 歸檔 archives: 歸檔
card_post_count: 評論 card_post_count: 評論
sticky: 置頂 no_title: 無標題
no_title: 無題
post: post:
created: 發表於 created: 發表於
updated: 更新於 updated: 更新於
wordcount: 字數總計 wordcount: 字數
min2read: 閱讀時 min2read: 閱讀時
min2read_unit: 分鐘 min2read_unit: 分鐘
page_pv: 閱讀 page_pv: 瀏覽
comments: 評論數 comments: 評論數
copyright: copyright:
author: 文章作者 author: 文章作者
link: 文章連結 link: 文章連結
copyright_notice: 版權聲明 copyright_notice: 版權聲明
copyright_content: '本部落格所有文章除特別聲明外,均採用 copyright_content: '本部落格所有文章除特別聲明外,均採用<a href="%s" target="_blank">%s</a> 授權協議。轉載請註明來源 <a href="%s" target="_blank">%s</a>'
<a href="%s" target="_blank">%s</a> 許可協議。轉載請註明來自 <a href="%s" target="_blank">%s</a>'
recommend: 相關推薦 recommend: 相關推薦
edit: 編輯 edit: 編輯
search: search:
title: 搜尋 title: 搜尋
load_data: 資料載入中 load_data: 資料載入中
input_placeholder: 搜尋文章
algolia_search: algolia_search:
input_placeholder: 搜尋文章 hits_empty: '找不到符合您查詢的內容:${query}'
hits_empty: '找不到您查詢的內容:${query}' hits_stats: '找到 ${hits} 筆結果,耗時 ${time} 毫秒'
hits_stats: '找到 ${hits} 條結果,用時 ${time} 毫秒'
local_search: local_search:
input_placeholder: 搜尋文章 hits_empty: '找不到符合您查詢的內容:${query}'
hits_empty: '找不到您查詢的內容:${query}' hits_stats: '共找到 ${hits} 篇文章'
pagination: pagination:
prev: 上一篇 prev: 上一篇
@@ -64,25 +61,26 @@ aside:
card_recent_post: 最新文章 card_recent_post: 最新文章
card_webinfo: card_webinfo:
headline: 網站資訊 headline: 網站資訊
article_name: 文章數 article_name: 文章數
runtime: runtime:
name: 已執行時間 name: 行時間
unit: unit:
last_push_date: last_push_date:
name: 最後更新時間 name: 最後更新時間
site_wordcount: 本站總字數 site_wordcount: 總字數
site_uv_name: 本站訪客數 site_uv_name: 訪客數
site_pv_name: 本站總訪問 site_pv_name: 總瀏覽
more_button: 檢視更多 more_button: 檢視更多
card_newest_comments: card_newest_comments:
headline: 最新評論 headline: 最新評論
loading_text: 正在載入中... loading_text: 載入中...
error: 無法獲取評論,請確認相關配置是否正確 error: 無法獲取評論,請確認相關配置是否正確
zero: 沒有評論 zero: 尚無評論
image: 圖片 image: 圖片
link: 連結 link: 連結
code: 程式碼 code: 程式碼
card_toc: 目錄 card_toc: 目錄
card_post_series: 系列文章
date_suffix: date_suffix:
just: 剛剛 just: 剛剛
@@ -91,16 +89,16 @@ date_suffix:
day: 天前 day: 天前
month: 個月前 month: 個月前
donate: 打賞 donate: 贊助
share: 分享 share: 分享
rightside: rightside:
readmode_title: 閱讀模式 readmode_title: 閱讀模式
translate_title: 繁轉換 translate_title: 轉換
night_mode_title: 淺色和深色模式 night_mode_title: 日夜模式
back_to_top: 回到頂 back_to_top: 回到頂
toc: 目錄 toc: 目錄
scroll_to_comment: 直達評論 scroll_to_comment: 前往評論
setting: 設定 setting: 設定
aside: 單欄和雙欄切換 aside: 單欄和雙欄切換
chat: 聊天 chat: 聊天
@@ -109,14 +107,15 @@ copy_copyright:
author: 作者 author: 作者
link: 連結 link: 連結
source: 來源 source: 來源
info: 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。 info: 著作權歸作者所有。如需商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
Snackbar: Snackbar:
chs_to_cht: 已切換為繁體 chs_to_cht: 已切換為繁體中文
cht_to_chs: 已切換為簡體 cht_to_chs: 已切換為簡體中文
day_to_night: 已切換為深色模式 day_to_night: 已切換為深色模式
night_to_day: 已切換為淺色模式 night_to_day: 已切換為淺色模式
loading: 載入中... loading: 載入中...
load_more: 載入更多
error404: 頁面沒有找到 error404: 找不到頁面

View File

@@ -3,6 +3,6 @@ extends includes/layout.pug
block content block content
include ./includes/mixins/article-sort.pug include ./includes/mixins/article-sort.pug
#archive #archive
.article-sort-title= _p('page.articles') + ' - ' + site.posts.length .article-sort-title= `${_p('page.articles')} - ${getArchiveLength()}`
+articleSort(page.posts) +articleSort(page.posts)
include includes/pagination.pug include includes/pagination.pug

View File

@@ -2,10 +2,8 @@ extends includes/layout.pug
block content block content
if theme.category_ui == 'index' if theme.category_ui == 'index'
include ./includes/mixins/post-ui.pug include ./includes/mixins/indexPostUI.pug
#recent-posts.recent-posts.category_ui +indexPostUI
+postUI
include includes/pagination.pug
else else
include ./includes/mixins/article-sort.pug include ./includes/mixins/article-sort.pug
#category #category

View File

@@ -1,12 +0,0 @@
- var top_img_404 = theme.error_404.background || theme.default_top_img
#body-wrap.error404
include ./header/index.pug
#error-wrap
.error-content
.error-img
img(src=url_for(top_img_404) alt='Page not found')
.error-info
h1.error_title= '404'
.error_subtitle= theme.error_404.subtitle || _p('error404')

View File

@@ -5,10 +5,8 @@ div
if theme.translate.enable if theme.translate.enable
script(src=url_for(theme.asset.translate)) script(src=url_for(theme.asset.translate))
if theme.medium_zoom if theme.lightbox
script(src=url_for(theme.asset.medium_zoom)) script(src=url_for(theme.asset[theme.lightbox]))
else if theme.fancybox
script(src=url_for(theme.asset.fancybox_v4))
if theme.instantpage if theme.instantpage
script(src=url_for(theme.asset.instantpage), type='module') script(src=url_for(theme.asset.instantpage), type='module')
@@ -22,17 +20,6 @@ div
if theme.pangu.enable if theme.pangu.enable
!= partial("includes/third-party/pangu.pug", {}, { cache: true }) != partial("includes/third-party/pangu.pug", {}, { cache: true })
//- search
if theme.algolia_search.enable
script(src=url_for(theme.asset.algolia_search_v4))
script(src=url_for(theme.asset.instantsearch_v4))
script(src=url_for(theme.asset.algolia_js))
else if theme.local_search.enable
script(src=url_for(theme.asset.local_search))
if theme.preloader
!= partial("includes/loading/loading-js", {}, { cache: true })
.js-pjax .js-pjax
if needLoadCountJs if needLoadCountJs
!= partial("includes/third-party/card-post-count/index", {}, { cache: true }) != partial("includes/third-party/card-post-count/index", {}, { cache: true })
@@ -41,32 +28,33 @@ div
include ./third-party/subtitle.pug include ./third-party/subtitle.pug
include ./third-party/math/index.pug include ./third-party/math/index.pug
include ./third-party/abcjs/index.pug
if commentsJsLoad if commentsJsLoad
include ./third-party/comments/js.pug include ./third-party/comments/js.pug
!= partial("includes/third-party/prismjs", {}, { cache: true }) != partial("includes/third-party/prismjs", {}, { cache: true })
if theme.aside.enable && theme.newest_comments.enable if theme.aside.enable && theme.aside.card_newest_comments.enable
if theme.pjax.enable if theme.pjax.enable || (!is_post() && page.aside !== false)
!= partial("includes/third-party/newest-comments/index", {}, { cache: true })
else if (!is_post() && page.aside !== false)
!= partial("includes/third-party/newest-comments/index", {}, { cache: true }) != partial("includes/third-party/newest-comments/index", {}, { cache: true })
!= fragment_cache('injectBottom', function(){return injectHtml(theme.inject.bottom)}) != fragment_cache('injectBottom', function(){return injectHtml(theme.inject.bottom)})
!= partial("includes/third-party/effect", {}, { cache: true }) != partial("includes/third-party/effect", {}, { cache: true })
!= partial("includes/third-party/chat/index", {}, { cache: true }) != partial("includes/third-party/chat/index", {}, { cache: true })
if theme.aplayerInject && theme.aplayerInject.enable if theme.aplayerInject && theme.aplayerInject.enable
if theme.pjax.enable || theme.aplayerInject.per_page if theme.pjax.enable || theme.aplayerInject.per_page || page.aplayer
include ./third-party/aplayer.pug
else if page.aplayer
include ./third-party/aplayer.pug include ./third-party/aplayer.pug
if theme.pjax.enable if theme.pjax.enable
!= partial("includes/third-party/pjax", {}, { cache: true }) != partial("includes/third-party/pjax", {}, { cache: true })
if theme.umami_analytics.enable
!= partial("includes/third-party/umami_analytics", {}, { cache: true })
if theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv if theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv
script(async data-pjax src='//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js') script(async data-pjax src= theme.asset.busuanzi || '//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js')
!= partial('includes/third-party/search/index', {}, { cache: true })

View File

@@ -1,11 +1,12 @@
#footer-wrap #footer-wrap
if theme.footer.owner.enable if theme.footer.owner.enable
- var now = new Date() - const currentYear = new Date().getFullYear()
- var nowYear = now.getFullYear() - const sinceYear = theme.footer.owner.since
if theme.footer.owner.since && theme.footer.owner.since != nowYear .copyright
.copyright!= `&copy;${theme.footer.owner.since} - ${nowYear} By ${config.author}` if sinceYear && sinceYear != currentYear
!= `&copy;${sinceYear} - ${currentYear} By ${config.author}`
else else
.copyright!= `&copy;${nowYear} By ${config.author}` != `&copy;${currentYear} By ${config.author}`
if theme.footer.copyright if theme.footer.copyright
.framework-info .framework-info
span= _p('footer.framework') + ' ' span= _p('footer.framework') + ' '
@@ -14,4 +15,4 @@
span= _p('footer.theme') + ' ' span= _p('footer.theme') + ' '
a(href='https://github.com/jerryc127/hexo-theme-butterfly')= 'Butterfly' a(href='https://github.com/jerryc127/hexo-theme-butterfly')= 'Butterfly'
if theme.footer.custom_text if theme.footer.custom_text
.footer_custom_text!=`${theme.footer.custom_text}` .footer_custom_text!= theme.footer.custom_text

View File

@@ -1,19 +1,12 @@
- var pageTitle - var pageTitle
- if (is_archive()) pageTitle = fragment_cache('findArchivesTitle', function(){return findArchivesTitle(theme.menu);}) - is_archive() ? page.title = findArchivesTitle(page, theme.menu, date) : ''
- else if (is_tag()) pageTitle = _p('page.tag') + ': ' + page.tag - if (is_tag()) pageTitle = _p('page.tag') + ': ' + page.tag
- else if (is_category()) pageTitle = _p('page.category') + ': ' + page.category - else if (is_category()) pageTitle = _p('page.category') + ': ' + page.category
- else if (is_month()) pageTitle += ': ' + page.month + '/' + page.year
- else if (is_year()) pageTitle += ': ' + page.year
- else if (is_current('/404.html', [strict])) pageTitle = _p('error404') - else if (is_current('/404.html', [strict])) pageTitle = _p('error404')
- else pageTitle = page.title || config.title || '' - else pageTitle = page.title || config.title || ''
- var isSubtitle = config.subtitle ? ' - ' + config.subtitle : '' - var isSubtitle = config.subtitle ? ' - ' + config.subtitle : ''
- var tabTitle = is_home() || !pageTitle ? config.title + isSubtitle : pageTitle + ' | ' + config.title - var tabTitle = is_home() || !pageTitle ? config.title + isSubtitle : pageTitle + ' | ' + config.title
- var pageKeywords
- if (page.keywords) pageKeywords = Array.isArray(page.keywords) ? (page.keywords).join(',') : ([]).join(',') || page.keywords
- else if (page.tags && page.tags.length) pageKeywords = page.tags.data.map(function(tag) {return tag.name;}).join(',')
- else pageKeywords = Array.isArray(config.keywords) ? (config.keywords).join(','): ([]).join(',') || config.keywords
- var pageAuthor = config.email ? config.author + ',' + config.email : config.author - var pageAuthor = config.email ? config.author + ',' + config.email : config.author
- var pageCopyright = config.copyright || config.author - var pageCopyright = config.copyright || config.author
- var themeColorLight = theme.theme_color && theme.theme_color.enable && theme.theme_color.meta_theme_color_light || '#ffffff' - var themeColorLight = theme.theme_color && theme.theme_color.enable && theme.theme_color.meta_theme_color_light || '#ffffff'
@@ -22,10 +15,8 @@
meta(charset='UTF-8') meta(charset='UTF-8')
meta(http-equiv="X-UA-Compatible" content="IE=edge") meta(http-equiv="X-UA-Compatible" content="IE=edge")
meta(name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no") meta(name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover")
title= tabTitle title= tabTitle
if pageKeywords
meta(name="keywords" content=pageKeywords)
meta(name="author" content=pageAuthor) meta(name="author" content=pageAuthor)
meta(name="copyright" content=pageCopyright) meta(name="copyright" content=pageCopyright)
meta(name ="format-detection" content="telephone=no") meta(name ="format-detection" content="telephone=no")
@@ -35,7 +26,7 @@ meta(name="theme-color" content=themeColor)
include ./head/Open_Graph.pug include ./head/Open_Graph.pug
!=favicon_tag(theme.favicon || config.favicon) !=favicon_tag(theme.favicon || config.favicon)
link(rel="canonical" href=urlNoIndex()) link(rel="canonical" href=urlNoIndex(null,config.pretty_urls.trailing_index,config.pretty_urls.trailing_html))
//- 預解析 //- 預解析
!=partial('includes/head/preconnect', {}, {cache: true}) !=partial('includes/head/preconnect', {}, {cache: true})
@@ -49,13 +40,15 @@ if (theme.pwa && theme.pwa.enable)
//- main css //- main css
link(rel='stylesheet', href=url_for(theme.asset.main_css)) link(rel='stylesheet', href=url_for(theme.asset.main_css))
link(rel='stylesheet', href=url_for(theme.asset.fontawesomeV6) media="print" onload="this.media='all'") link(rel='stylesheet', href=url_for(theme.asset.fontawesome))
if (theme.snackbar && theme.snackbar.enable) if (theme.snackbar && theme.snackbar.enable)
link(rel='stylesheet', href=url_for(theme.asset.snackbar_css) media="print" onload="this.media='all'") link(rel='stylesheet', href=url_for(theme.asset.snackbar_css) media="print" onload="this.media='all'")
if theme.fancybox if theme.lightbox === 'fancybox'
link(rel='stylesheet' href=url_for(theme.asset.fancybox_css_v4) media="print" onload="this.media='all'") link(rel='stylesheet' href=url_for(theme.asset.fancybox_css) media="print" onload="this.media='all'")
!=fragment_cache('injectHeadJs', function(){return inject_head_js()})
//- google_adsense //- google_adsense
!=partial('includes/head/google_adsense', {}, {cache: true}) !=partial('includes/head/google_adsense', {}, {cache: true})
@@ -64,15 +57,12 @@ if theme.fancybox
!=partial('includes/head/analytics', {}, {cache: true}) !=partial('includes/head/analytics', {}, {cache: true})
//- font //- font
if theme.blog_title_font && theme.blog_title_font.font_link if theme.blog_title_font && theme.blog_title_font.font_link
link(rel='stylesheet' href=url_for(theme.blog_title_font.font_link) media="print" onload="this.media='all'") link(rel='stylesheet' href=url_for(theme.blog_title_font.font_link) media="print" onload="this.media='all'")
//- global config //- global config
!=partial('includes/head/config', {}, {cache: true}) !=partial('includes/head/config', {}, {cache: true})
include ./head/config_site.pug include ./head/config_site.pug
include ./head/noscript.pug
!=fragment_cache('injectHeadJs', function(){return inject_head_js()})
!=fragment_cache('injectHead', function(){return injectHtml(theme.inject.head)}) !=fragment_cache('injectHead', function(){return injectHtml(theme.inject.head)})

View File

@@ -1,11 +1,16 @@
if theme.Open_Graph_meta if theme.Open_Graph_meta.enable
- let contentType = is_post() ? 'article' : 'website' -
- let metaImage = (page.cover || theme.avatar.img) ? full_url_for(page.cover || theme.avatar.img) : '' const coverVal = page.cover_type === 'img' ? page.cover : theme.avatar.img
- let fb_appId = theme.facebook_comments.app_id || '' let ogOption = Object.assign({
- let fb_admins = theme.facebook_comments.user_id || '' type: is_post() ? 'article' : 'website',
image: coverVal ? full_url_for(coverVal) : '',
!= open_graph({type: contentType, image: metaImage, fb_admins: fb_admins, fb_app_id: fb_appId}) fb_admins: theme.facebook_comments.user_id || '',
fb_app_id: theme.facebook_comments.app_id || '',
}, theme.Open_Graph_meta.option)
-
!= open_graph(ogOption)
else else
meta(name="description" content=page_description()) - const description = page.description || page.content || page.title || config.description
if description
meta(name="description" content=truncate(description, 150))

View File

@@ -7,17 +7,20 @@ if theme.baidu_analytics
var s = document.getElementsByTagName("script")[0]; var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s); s.parentNode.insertBefore(hm, s);
})(); })();
btf.addGlobalFn('pjaxComplete', () => {
_hmt.push(['_trackPageview',window.location.pathname])
}, 'baidu_analytics')
if theme.google_analytics if theme.google_analytics
script(async src=`https://www.googletagmanager.com/gtag/js?id=${theme.google_analytics}`) script(async src=`https://www.googletagmanager.com/gtag/js?id=${theme.google_analytics}`)
script. script.
window.dataLayer = window.dataLayer || []; window.dataLayer = window.dataLayer || []
function gtag(){dataLayer.push(arguments);} function gtag(){dataLayer.push(arguments)}
gtag('js', new Date()); gtag('js', new Date())
gtag('config', '!{theme.google_analytics}'); gtag('config', '!{theme.google_analytics}')
btf.addGlobalFn('pjaxComplete', () => {
if theme.cnzz_analytics gtag('config', '!{theme.google_analytics}', {'page_path': window.location.pathname})
script(async data-pjax src=`https://s4.cnzz.com/z_stat.php?id=${theme.cnzz_analytics}&web_id=${theme.cnzz_analytics}`) }, 'google_analytics')
if theme.cloudflare_analytics if theme.cloudflare_analytics
script(defer data-pjax src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon=`{"token": "${theme.cloudflare_analytics}"}`) script(defer data-pjax src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon=`{"token": "${theme.cloudflare_analytics}"}`)

View File

@@ -1,34 +1,39 @@
- -
let algolia = 'undefined'; let algolia = 'undefined'
let env = process.env; if (theme.search.use === 'algolia_search') {
if (theme.algolia_search.enable) { const { ALGOLIA_APP_ID, ALGOLIA_API_KEY, ALGOLIA_INDEX_NAME } = process.env
const { appId, applicationID, apiKey, indexName } = config.algolia
algolia = JSON.stringify({ algolia = JSON.stringify({
appId: env.ALGOLIA_APP_ID || config.algolia.appId || config.algolia.applicationID, appId: ALGOLIA_APP_ID || appId || applicationID,
apiKey: env.ALGOLIA_API_KEY || config.algolia.apiKey, apiKey: ALGOLIA_API_KEY || apiKey,
indexName: env.ALGOLIA_INDEX_NAME || config.algolia.indexName, indexName: ALGOLIA_INDEX_NAME || indexName,
hits: theme.algolia_search.hits, hitsPerPage: theme.search.algolia_search.hitsPerPage,
// search languages // search languages
languages: { languages: {
input_placeholder: _p("search.algolia_search.input_placeholder"), input_placeholder: theme.search.placeholder || _p("search.input_placeholder"),
hits_empty: _p("search.algolia_search.hits_empty"), hits_empty: _p("search.algolia_search.hits_empty"),
hits_stats: _p("search.algolia_search.hits_stats"), hits_stats: _p("search.algolia_search.hits_stats"),
} }
}) })
} }
let localSearch = 'undefined'; let localSearch = 'undefined'
if (theme.local_search && theme.local_search.enable) { if (theme.search.use === 'local_search') {
const { CDN, preload, top_n_per_article, unescape } = theme.search.local_search
localSearch = JSON.stringify({ localSearch = JSON.stringify({
path: theme.local_search.CDN ? theme.local_search.CDN : config.root + config.search.path, path: CDN || config.root + config.search.path,
preload: theme.local_search.preload, preload,
top_n_per_article,
unescape,
languages: { languages: {
// search languages // search languages
hits_empty: _p("search.local_search.hits_empty"), hits_empty: _p("search.local_search.hits_empty"),
hits_stats: _p("search.local_search.hits_stats"),
} }
}) })
} }
let translate = 'undefined'; let translate = 'undefined'
if (theme.translate && theme.translate.enable){ if (theme.translate && theme.translate.enable){
translate = JSON.stringify({ translate = JSON.stringify({
defaultEncoding: theme.translate.defaultEncoding, defaultEncoding: theme.translate.defaultEncoding,
@@ -38,7 +43,7 @@
}) })
} }
let copyright = 'undefined'; let copyright = 'undefined'
if (theme.copy.enable && theme.copy.copyright.enable){ if (theme.copy.enable && theme.copy.copyright.enable){
copyright = JSON.stringify({ copyright = JSON.stringify({
limitCount: theme.copy.copyright.limit_count, limitCount: theme.copy.copyright.limit_count,
@@ -51,7 +56,7 @@
}) })
} }
let Snackbar = 'undefined'; let Snackbar = 'undefined'
if (theme.snackbar && theme.snackbar.enable) { if (theme.snackbar && theme.snackbar.enable) {
Snackbar = JSON.stringify({ Snackbar = JSON.stringify({
chs_to_cht: _p("Snackbar.chs_to_cht"), chs_to_cht: _p("Snackbar.chs_to_cht"),
@@ -64,7 +69,7 @@
}) })
} }
let noticeOutdate = 'undefined'; let noticeOutdate = 'undefined'
if (theme.noticeOutdate && theme.noticeOutdate.enable) { if (theme.noticeOutdate && theme.noticeOutdate.enable) {
noticeOutdate = JSON.stringify({ noticeOutdate = JSON.stringify({
limitDay: theme.noticeOutdate.limit_day, limitDay: theme.noticeOutdate.limit_day,
@@ -74,13 +79,18 @@
}) })
} }
let highlight = 'undefined'; let highlight = 'undefined'
if ((config.highlight && config.highlight.enable) || (config.prismjs && config.prismjs.enable)) { let syntaxHighlighter = config.syntax_highlighter
let highlightEnable = syntaxHighlighter ? ['highlight.js', 'prismjs'].includes(syntaxHighlighter) : (config.highlight.enable || config.prismjs.enable)
if (highlightEnable) {
const { copy, language, height_limit, fullpage, macStyle } = theme.code_blocks
highlight = JSON.stringify({ highlight = JSON.stringify({
plugin: config.highlight.enable ? 'highlighjs' : 'prismjs', plugin: syntaxHighlighter ? syntaxHighlighter : config.highlight.enable ? 'highlight.js' : 'prismjs',
highlightCopy: theme.highlight_copy, highlightCopy: copy,
highlightLang: theme.highlight_lang, highlightLang: language,
highlightHeightLimit: theme.highlight_height_limit highlightHeightLimit: height_limit,
highlightFullpage: fullpage,
highlightMacStyle: macStyle
}) })
} }
@@ -101,8 +111,8 @@ script.
homepage: !{theme.post_meta.page.date_format === 'relative'}, homepage: !{theme.post_meta.page.date_format === 'relative'},
post: !{theme.post_meta.post.date_format === 'relative'} post: !{theme.post_meta.post.date_format === 'relative'}
}, },
runtime: '!{theme.runtimeshow.enable ? _p("aside.card_webinfo.runtime.unit") : ""}', runtime: '!{theme.aside.card_webinfo.runtime_date ? _p("aside.card_webinfo.runtime.unit") : ""}',
date_suffix: { dateSuffix: {
just: '!{_p("date_suffix.just")}', just: '!{_p("date_suffix.just")}',
min: '!{_p("date_suffix.min")}', min: '!{_p("date_suffix.min")}',
hour: '!{_p("date_suffix.hour")}', hour: '!{_p("date_suffix.hour")}',
@@ -110,15 +120,18 @@ script.
month: '!{_p("date_suffix.month")}' month: '!{_p("date_suffix.month")}'
}, },
copyright: !{copyright}, copyright: !{copyright},
lightbox: '!{ theme.medium_zoom ? "mediumZoom" : (theme.fancybox ? "fancybox" : "null" )}', lightbox: '!{ theme.lightbox || 'null' }',
Snackbar: !{Snackbar}, Snackbar: !{Snackbar},
source: { infinitegrid: {
justifiedGallery: { js: '!{url_for(theme.asset.egjs_infinitegrid)}',
js: '!{url_for(theme.asset.flickr_justified_gallery_js)}', buttonText: '!{_p("load_more")}'
css: '!{url_for(theme.asset.flickr_justified_gallery_css)}'
}
}, },
isPhotoFigcaption: !{theme.photofigcaption}, isPhotoFigcaption: !{theme.photofigcaption},
islazyload: !{theme.lazyload.enable}, islazyload: !{theme.lazyload.enable},
isAnchor: !{theme.anchor} isAnchor: !{theme.anchor.auto_update || false},
percent: {
toc: !{theme.toc.scroll_percent},
rightside: !{theme.rightside_scroll_percent},
},
autoDarkmode: !{theme.darkmode.enable && theme.darkmode.autoChangeMode === 1}
} }

View File

@@ -2,20 +2,17 @@
const titleVal = pageTitle.replace(/'/ig,"\\'") const titleVal = pageTitle.replace(/'/ig,"\\'")
let isHighlightShrink let isHighlightShrink
if (theme.highlight_shrink == 'none') isHighlightShrink = 'undefined' if (theme.code_blocks.shrink == 'none') isHighlightShrink = 'undefined'
else if (page.highlight_shrink === true || page.highlight_shrink === false) isHighlightShrink = page.highlight_shrink else if (typeof page.highlight_shrink == 'boolean') isHighlightShrink = page.highlight_shrink
else isHighlightShrink = theme.highlight_shrink else isHighlightShrink = theme.code_blocks.shrink
var showToc = false var showToc = false
if (theme.aside.enable && page.aside !== false) { if (theme.aside.enable && page.aside !== false) {
let tocEnable = false let tocEnable = false
if (is_post()) { if (is_post() && theme.toc.post) tocEnable = true
if (theme.toc.post) tocEnable = true else if (is_page() && theme.toc.page) tocEnable = true
} else if (is_page()) { const pageToc = typeof page.toc === 'boolean' ? page.toc : tocEnable
if (theme.toc.page) tocEnable = true showToc = pageToc && (toc(page.content) !== '' || page.encrypt === true)
}
const pageToc = page.toc === true || page.toc === false ? page.toc : tocEnable
showToc = pageToc && (toc(page.content) !== '' || page.encrypt == true )
} }
- -

View File

@@ -1,14 +0,0 @@
noscript.
<style type="text/css">
#nav {
opacity: 1
}
.justified-gallery img {
opacity: 1
}
#recent-posts time,
#post-meta time {
display: inline !important
}
</style>

View File

@@ -1,4 +1,20 @@
link(rel="preconnect" href="//cdn.jsdelivr.net") -
const { internal_provider, third_party_provider, custom_format } = theme.CDN
const providers = {
'jsdelivr': '//cdn.jsdelivr.net',
'cdnjs': '//cdnjs.cloudflare.com',
'unpkg': '//unpkg.com',
'custom': custom_format && custom_format.match(/^((https?:)?(\/\/[^/]+)|([^/]+))(\/|$)/)[1]
}
-
if internal_provider === third_party_provider && internal_provider !== 'local'
link(rel="preconnect" href=providers[internal_provider])
else
if internal_provider !== 'local'
link(rel="preconnect" href=providers[internal_provider])
if third_party_provider !== 'local'
link(rel="preconnect" href=providers[third_party_provider])
if theme.google_analytics if theme.google_analytics
link(rel="preconnect" href="//www.google-analytics.com" crossorigin='') link(rel="preconnect" href="//www.google-analytics.com" crossorigin='')
@@ -6,9 +22,6 @@ if theme.google_analytics
if theme.baidu_analytics if theme.baidu_analytics
link(rel="preconnect" href="//hm.baidu.com") link(rel="preconnect" href="//hm.baidu.com")
if theme.cnzz_analytics
link(rel="preconnect" href="//s4.cnzz.com")
if theme.cloudflare_analytics if theme.cloudflare_analytics
link(rel="preconnect" href="//static.cloudflareinsights.com") link(rel="preconnect" href="//static.cloudflareinsights.com")
@@ -18,5 +31,5 @@ if theme.microsoft_clarity
if theme.blog_title_font && theme.blog_title_font.font_link && theme.blog_title_font.font_link.indexOf('//fonts.googleapis.com') != -1 if theme.blog_title_font && theme.blog_title_font.font_link && theme.blog_title_font.font_link.indexOf('//fonts.googleapis.com') != -1
link(rel="preconnect" href="//fonts.googleapis.com" crossorigin='') link(rel="preconnect" href="//fonts.googleapis.com" crossorigin='')
if theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv if !theme.asset.busuanzi && (theme.busuanzi.site_uv || theme.busuanzi.site_pv || theme.busuanzi.page_pv)
link(rel="preconnect" href="//busuanzi.ibruce.info") link(rel="preconnect" href="//busuanzi.ibruce.info")

View File

@@ -1,11 +1,13 @@
link(rel="manifest" href=url_for(theme.pwa.manifest)) - const { manifest, theme_color, apple_touch_icon, favicon_32_32, favicon_16_16, mask_icon } = theme.pwa
if(theme.pwa.theme_color)
meta(name="msapplication-TileColor" content=theme.pwa.theme_color) link(rel="manifest" href=url_for(manifest))
if(theme.pwa.apple_touch_icon) if theme_color
link(rel="apple-touch-icon" sizes="180x180" href=url_for(theme.pwa.apple_touch_icon)) meta(name="msapplication-TileColor" content=theme_color)
if(theme.pwa.favicon_32_32) if apple_touch_icon
link(rel="icon" type="image/png" sizes="32x32" href=url_for(theme.pwa.favicon_32_32)) link(rel="apple-touch-icon" sizes="180x180" href=url_for(apple_touch_icon))
if(theme.pwa.favicon_16_16) if favicon_32_32
link(rel="icon" type="image/png" sizes="16x16" href=url_for(theme.pwa.favicon_16_16)) link(rel="icon" type="image/png" sizes="32x32" href=url_for(favicon_32_32))
if(theme.pwa.mask_icon) if favicon_16_16
link(rel="mask-icon" href=url_for(theme.pwa.mask_icon) color="#5bbad5") link(rel="icon" type="image/png" sizes="16x16" href=url_for(favicon_16_16))
if mask_icon
link(rel="mask-icon" href=url_for(mask_icon) color="#5bbad5")

View File

@@ -1,50 +1,53 @@
-
const returnTopImg = img => img !== false ? img || theme.default_top_img : false
const isFixedClass = theme.nav.fixed ? ' fixed' : ''
var top_img = false
let headerClassName = 'not-top-img'
var bg_img = ''
if !theme.disable_top_img && page.top_img !== false if !theme.disable_top_img && page.top_img !== false
if is_post() if is_post()
- var top_img = page.top_img || page.cover || page.randomcover - top_img = page.top_img || page.cover || theme.default_top_img
else if is_page() else if is_page()
- var top_img = page.top_img || theme.default_top_img - top_img = page.top_img || theme.default_top_img
else if is_tag() else if is_tag()
- var top_img = theme.tag_per_img && theme.tag_per_img[page.tag] - top_img = theme.tag_per_img && theme.tag_per_img[page.tag]
- top_img = top_img ? top_img : (theme.tag_img !== false ? theme.tag_img || theme.default_top_img : false) - top_img = top_img || returnTopImg(theme.tag_img)
else if is_category() else if is_category()
- var top_img = theme.category_per_img && theme.category_per_img[page.category] - top_img = theme.category_per_img && theme.category_per_img[page.category]
- top_img = top_img ? top_img : (theme.category_img !== false ? theme.category_img || theme.default_top_img : false) - top_img = top_img || returnTopImg(theme.category_img)
else if is_home() else if is_home()
- var top_img = theme.index_img !== false ? theme.index_img || theme.default_top_img : false - top_img = returnTopImg(theme.index_img)
else if is_archive() else if is_archive()
- var top_img = theme.archive_img !== false ? theme.archive_img || theme.default_top_img : false - top_img = returnTopImg(theme.archive_img)
else else
- var top_img = page.top_img || theme.default_top_img - top_img = page.top_img || theme.default_top_img
if top_img !== false if top_img !== false
- var imgSource = top_img && top_img.indexOf('/') !== -1 ? `background-image: url('${url_for(top_img)}')` : `background: ${top_img}` - bg_img = getBgPath(top_img)
- var bg_img = top_img ? imgSource : '' - headerClassName = is_home() ? 'full_page' : is_post() ? 'post-bg' : 'not-home-page'
- var site_title = is_archive() ? fragment_cache('findArchivesTitle', function(){return findArchivesTitle(theme.menu);}) : page.title || page.tag || page.category || config.title
- var isHomeClass = is_home() ? 'full_page' : 'not-home-page'
- is_post() ? isHomeClass = 'post-bg' : isHomeClass
else
- var isHomeClass = 'not-top-img'
else
- var top_img = false
- var isHomeClass = 'not-top-img'
header#page-header(class=isHomeClass style=bg_img) header#page-header(class=`${headerClassName + isFixedClass}` style=bg_img)
!=partial('includes/header/nav', {}, {cache: true}) include ./nav.pug
if top_img !== false if top_img !== false
if is_post() if is_post()
include ./post-info.pug include ./post-info.pug
else if is_home() else if is_home()
#site-info #site-info
h1#site-title=site_title h1#site-title=config.title
if theme.subtitle.enable if theme.subtitle.enable
- var loadSubJs = true - var loadSubJs = true
#site-subtitle #site-subtitle
span#subtitle span#subtitle
if(theme.social) if theme.social
#site_social_icons #site_social_icons
!=fragment_cache('social', function(){return partial('includes/header/social')}) !=partial('includes/header/social', {}, {cache: true})
#scroll-down #scroll-down
i.fas.fa-angle-down.scroll-down-effects i.fas.fa-angle-down.scroll-down-effects
else else
#page-site-info #page-site-info
h1#site-title=site_title h1#site-title=page.title || page.tag || page.category
else
//- improvement seo
if !is_post()
h1.title-seo=page.title || page.tag || page.category || config.title

View File

@@ -3,25 +3,25 @@ if theme.menu
each value, label in theme.menu each value, label in theme.menu
if typeof value !== 'object' if typeof value !== 'object'
.menus_item .menus_item
- const valueArray = value.split('||') - const [link, icon] = value.split('||').map(part => trim(part))
a.site-page(href=url_for(trim(valueArray[0]))) a.site-page(href=url_for(link))
if valueArray[1] if icon
i.fa-fw(class=trim(valueArray[1])) i.fa-fw(class=icon)
span= ' ' + label span= ' ' + label
else else
.menus_item .menus_item
- const labelArray = label.split('||') - const [groupLabel, groupIcon, groupClass] = label.split('||').map(part => trim(part))
- const hideClass = labelArray[2] && trim(labelArray[2]) === 'hide' ? 'hide' : '' - const hideClass = groupClass === 'hide' ? 'hide' : ''
a.site-page.group(class=`${hideClass}` href='javascript:void(0);') span.site-page.group(class=hideClass)
if labelArray[1] if groupIcon
i.fa-fw(class=trim(labelArray[1])) i.fa-fw(class=groupIcon)
span=' '+ trim(labelArray[0]) span= ' ' + groupLabel
i.fas.fa-chevron-down i.fas.fa-chevron-down
ul.menus_item_child ul.menus_item_child
each val, lab in value each val, lab in value
- const valArray = val.split('||') - const [childLink, childIcon] = val.split('||').map(part => trim(part))
li li
a.site-page.child(href=url_for(trim(valArray[0]))) a.site-page.child(href=url_for(childLink))
if valArray[1] if childIcon
i.fa-fw(class=trim(valArray[1])) i.fa-fw(class=childIcon)
span= ' ' + lab span= ' ' + lab

View File

@@ -1,17 +1,22 @@
nav#nav nav#nav
span#blog_name span#blog-info
a#site-name(href=url_for('/')) #[=config.title] a.nav-site-title(href=url_for('/'))
if theme.nav.logo
img.site-icon(src=url_for(theme.nav.logo) alt='Logo')
if theme.nav.display_title
span.site-name=config.title
if is_post()
a.nav-page-title(href=url_for('/'))
span.site-name=(page.title || config.title)
#menus #menus
if (theme.algolia_search.enable || theme.local_search.enable) if theme.search.use
#search-button #search-button
a.site-page.social-icon.search span.site-page.social-icon.search
i.fas.fa-search.fa-fw i.fas.fa-search.fa-fw
span= ' ' + _p('search.title') span= ' ' + _p('search.title')
if theme.menu
!= partial('includes/header/menu_item', {}, {cache: true}) != partial('includes/header/menu_item', {}, {cache: true})
#toggle-menu #toggle-menu
a.site-page span.site-page
i.fas.fa-bars.fa-fw i.fas.fa-bars.fa-fw

View File

@@ -7,9 +7,9 @@
#post-meta #post-meta
.meta-firstline .meta-firstline
if (theme.post_meta.post.date_type) if theme.post_meta.post.date_type
span.post-meta-date span.post-meta-date
if (theme.post_meta.post.date_type === 'both') if theme.post_meta.post.date_type === 'both'
i.far.fa-calendar-alt.fa-fw.post-meta-icon i.far.fa-calendar-alt.fa-fw.post-meta-icon
span.post-meta-label= _p('post.created') span.post-meta-label= _p('post.created')
time.post-meta-date-created(datetime=date_xml(page.date) title=_p('post.created') + ' ' + full_date(page.date))= date(page.date, config.date_format) time.post-meta-date-created(datetime=date_xml(page.date) title=_p('post.created') + ' ' + full_date(page.date))= date(page.date, config.date_format)
@@ -25,20 +25,19 @@
i.fa-fw.post-meta-icon(class=date_icon) i.fa-fw.post-meta-icon(class=date_icon)
span.post-meta-label= date_title span.post-meta-label= date_title
time(datetime=date_xml(page[date_type]) title=date_title + ' ' + full_date(page[date_type]))= date(page[date_type], config.date_format) time(datetime=date_xml(page[date_type]) title=date_title + ' ' + full_date(page[date_type]))= date(page[date_type], config.date_format)
if (theme.post_meta.post.categories && page.categories.data.length > 0) if theme.post_meta.post.categories && page.categories.data.length > 0
span.post-meta-categories span.post-meta-categories
if (theme.post_meta.post.date_type) if theme.post_meta.post.date_type
span.post-meta-separator | span.post-meta-separator |
each item, index in page.categories.data each item, index in page.categories.data
i.fas.fa-inbox.fa-fw.post-meta-icon i.fas.fa-inbox.fa-fw.post-meta-icon
a(href=url_for(item.path)).post-meta-categories #[=item.name] a(href=url_for(item.path)).post-meta-categories #[=item.name]
if (index < page.categories.data.length - 1) if index < page.categories.data.length - 1
i.fas.fa-angle-right.post-meta-separator i.fas.fa-angle-right.post-meta-separator
.meta-secondline .meta-secondline
- let postWordcount = theme.wordcount.enable && (theme.wordcount.post_wordcount || theme.wordcount.min2read) - let postWordcount = theme.wordcount.enable && (theme.wordcount.post_wordcount || theme.wordcount.min2read)
if (postWordcount) if postWordcount
span.post-meta-separator | span.post-meta-separator |
span.post-meta-wordcount span.post-meta-wordcount
if theme.wordcount.post_wordcount if theme.wordcount.post_wordcount
@@ -55,30 +54,53 @@
//- for pv and count //- for pv and count
mixin pvBlock(parent_id, parent_class, parent_title) mixin pvBlock(parent_id, parent_class, parent_title)
span.post-meta-separator | span.post-meta-separator |
span(class=parent_class id=parent_id data-flag-title=page.title) span(class=parent_class id=parent_id data-flag-title=parent_title)
i.far.fa-eye.fa-fw.post-meta-icon i.far.fa-eye.fa-fw.post-meta-icon
span.post-meta-label= _p('post.page_pv') + ':' span.post-meta-label= _p('post.page_pv') + ':'
if block if block
block block
- const commentUse = comments.use - const commentUse = comments.use && comments.use[0]
if commentUse && !comments.lazyload if page.comments !== false && commentUse && !comments.lazyload
case commentUse[0] case commentUse
when 'Valine' when 'Valine'
if theme.valine.visitor if theme.valine.visitor
+pvBlock(url_for(page.path), 'leancloud_visitors', page.title) +pvBlock(url_for(page.path), 'leancloud_visitors', page.title)
span.leancloud-visitors-count span.leancloud-visitors-count
i.fa-solid.fa-spinner.fa-spin
when 'Waline' when 'Waline'
if theme.waline.pageview if theme.waline.pageview
+pvBlock('', '', '') +pvBlock('', '', '')
span.waline-pageview-count(data-path=url_for(page.path)) span.waline-pageview-count(data-path=url_for(page.path))
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo' when 'Twikoo'
if theme.twikoo.visitor if theme.twikoo.visitor
+pvBlock('', '', '') +pvBlock('', '', '')
span#twikoo_visitors span#twikoo_visitors
i.fa-solid.fa-spinner.fa-spin
when 'Artalk'
if theme.artalk.visitor
+pvBlock('', '', '')
span#ArtalkPV
i.fa-solid.fa-spinner.fa-spin
default
if theme.umami_analytics.enable && theme.umami_analytics.UV_PV.page_pv
+pvBlock('', '', '')
span#umamiPV(data-path=url_for(page.path))
i.fa-solid.fa-spinner.fa-spin
else if theme.busuanzi.page_pv else if theme.busuanzi.page_pv
+pvBlock('', 'post-meta-pv-cv', '') +pvBlock('', 'post-meta-pv-cv', '')
span#busuanzi_value_page_pv span#busuanzi_value_page_pv
i.fa-solid.fa-spinner.fa-spin
else
if theme.umami_analytics.enable && theme.umami_analytics.UV_PV.page_pv
+pvBlock('', '', '')
span#umamiPV(data-path=url_for(page.path))
i.fa-solid.fa-spinner.fa-spin
else if theme.busuanzi.page_pv
+pvBlock('', 'post-meta-pv-cv', '')
span#busuanzi_value_page_pv
i.fa-solid.fa-spinner.fa-spin
if comments.count && !comments.lazyload && page.comments !== false && comments.use if comments.count && !comments.lazyload && page.comments !== false && comments.use
- var whichCount = comments.use[0] - var whichCount = comments.use[0]
@@ -93,27 +115,44 @@
case whichCount case whichCount
when 'Disqus' when 'Disqus'
+countBlock
a.disqus-comment-count(href=full_url_for(page.path) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Disqusjs' when 'Disqusjs'
+countBlock +countBlock
span.disqus-comment-count a.disqusjs-comment-count(href=full_url_for(page.path) + '#post-comment')
a(href=full_url_for(page.path) + '#disqus_thread') i.fa-solid.fa-spinner.fa-spin
when 'Valine' when 'Valine'
+countBlock +countBlock
a(href=url_for(page.path) + '#post-comment' itemprop="discussionUrl") a(href=url_for(page.path) + '#post-comment' itemprop="discussionUrl")
span.valine-comment-count(data-xid=url_for(page.path) itemprop="commentCount") span.valine-comment-count(data-xid=url_for(page.path) itemprop="commentCount")
i.fa-solid.fa-spinner.fa-spin
when 'Waline' when 'Waline'
+countBlock +countBlock
a(href=url_for(page.path) + '#post-comment') a(href=url_for(page.path) + '#post-comment')
span.waline-comment-count(data-path=url_for(page.path)) span.waline-comment-count(data-path=url_for(page.path))
i.fa-solid.fa-spinner.fa-spin
when 'Gitalk' when 'Gitalk'
+countBlock +countBlock
a(href=url_for(page.path) + '#post-comment') a(href=url_for(page.path) + '#post-comment')
span.gitalk-comment-count span.gitalk-comment-count
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo' when 'Twikoo'
+countBlock +countBlock
a(href=url_for(page.path) + '#post-comment') a(href=url_for(page.path) + '#post-comment')
span#twikoo-count span#twikoo-count
i.fa-solid.fa-spinner.fa-spin
when 'Facebook Comments' when 'Facebook Comments'
+countBlock +countBlock
a(href=url_for(page.path) + '#post-comment') a(href=url_for(page.path) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex()) span.fb-comments-count(data-href=urlNoIndex())
when 'Remark42'
+countBlock
a(href=url_for(page.path) + '#post-comment')
span.remark42__counter(data-url=urlNoIndex())
i.fa-solid.fa-spinner.fa-spin
when 'Artalk'
+countBlock
a(href=url_for(page.path) + '#post-comment')
span#ArtalkCount
i.fa-solid.fa-spinner.fa-spin

View File

@@ -1,4 +1,8 @@
each url, icon in theme.social each url, icon in theme.social
a.social-icon(href=url_for(trim(url.split('||')[0])) target="_blank" -
title=url.split('||')[1] === undefined ? '' : trim(url.split('||')[1])) const [link, title, color] = url.split('||').map(i => trim(i))
i(class=icon) const href = url_for(link)
const iconStyle = color ? `color: ${color.replace(/[\'\"]/g, '')};` : ''
const iconTitle = title || ''
a.social-icon(href=href target="_blank" title=iconTitle)
i(class=icon style=iconStyle)

View File

@@ -1,22 +1,21 @@
- var htmlClassHideAside = theme.aside.enable && theme.aside.hide ? 'hide-aside' : '' - var htmlClassHideAside = theme.aside.enable && theme.aside.hide ? 'hide-aside' : ''
- page.aside = is_archive() ? theme.aside.archives : page.aside - page.aside = is_archive() ? theme.aside.display.archive: is_category() ? theme.aside.display.category : is_tag() ? theme.aside.display.tag : page.aside
- var hideAside = !theme.aside.enable || page.aside === false ? 'hide-aside' : '' - var hideAside = !theme.aside.enable || page.aside === false ? 'hide-aside' : ''
- var pageType = is_post() ? 'post' : 'page' - var pageType = is_post() ? 'post' : 'page'
- pageType = page.type ? pageType + ' type-' + page.type : pageType
doctype html doctype html
html(lang=config.language data-theme=theme.display_mode class=htmlClassHideAside) html(lang=config.language data-theme=theme.display_mode class=htmlClassHideAside)
head head
include ./head.pug include ./head.pug
body body
if theme.preloader !=partial('includes/loading/index', {}, {cache: true})
!=partial('includes/loading/loading', {}, {cache: true})
if theme.background if theme.background
#web_bg #web_bg(style=getBgPath(theme.background))
!=partial('includes/sidebar', {}, {cache: true}) !=partial('includes/sidebar', {}, {cache: true})
if page.type !== '404'
#body-wrap(class=pageType) #body-wrap(class=pageType)
include ./header/index.pug include ./header/index.pug
@@ -28,21 +27,10 @@ html(lang=config.language data-theme=theme.display_mode class=htmlClassHideAside
if theme.aside.enable && page.aside !== false if theme.aside.enable && page.aside !== false
include widget/index.pug include widget/index.pug
- var footerBg = theme.footer_bg - const footerBg = theme.footer_img
if (footerBg) - const footer_bg = footerBg ? footerBg === true ? bg_img : getBgPath(footerBg) : ''
if (footerBg === true)
- var footer_bg = bg_img
else
- var footer_bg = theme.footer_bg.indexOf('/') !== -1 ? `background-image: url('${url_for(footerBg)}')` : `background: ${footerBg}`
else
- var footer_bg = ''
footer#footer(style=footer_bg) footer#footer(style=footer_bg)
!=partial('includes/footer', {}, {cache: true}) !=partial('includes/footer', {}, {cache: true})
else
include ./404.pug
include ./rightside.pug include ./rightside.pug
!=partial('includes/third-party/search/index', {}, {cache: true})
include ./additional-js.pug include ./additional-js.pug

View File

@@ -0,0 +1,33 @@
#loading-box
.loading-left-bg
.loading-right-bg
.spinner-box
.configure-border-1
.configure-core
.configure-border-2
.configure-core
.loading-word= _p('loading')
script.
(()=>{
const $loadingBox = document.getElementById('loading-box')
const $body = document.body
const preloader = {
endLoading: () => {
$body.style.overflow = ''
$loadingBox.classList.add('loaded')
},
initLoading: () => {
$body.style.overflow = 'hidden'
$loadingBox.classList.remove('loaded')
}
}
preloader.initLoading()
window.addEventListener('load', preloader.endLoading)
if (!{theme.pjax && theme.pjax.enable}) {
btf.addGlobalFn('pjaxSend', preloader.initLoading, 'preloader_init')
btf.addGlobalFn('pjaxComplete', preloader.endLoading, 'preloader_end')
}
})()

View File

@@ -0,0 +1,5 @@
if theme.preloader.enable
if theme.preloader.source === 1
include ./fullpage-loading.pug
else
include ./pace.pug

View File

@@ -1,13 +0,0 @@
script.
var preloader = {
endLoading: () => {
document.body.style.overflow = 'auto';
document.getElementById('loading-box').classList.add("loaded")
},
initLoading: () => {
document.body.style.overflow = '';
document.getElementById('loading-box').classList.remove("loaded")
}
}
window.addEventListener('load',preloader.endLoading())

View File

@@ -1,9 +0,0 @@
#loading-box
.loading-left-bg
.loading-right-bg
.spinner-box
.configure-border-1
.configure-core
.configure-border-2
.configure-core
.loading-word= _p('loading')

View File

@@ -0,0 +1,12 @@
script.
window.paceOptions = {
restartOnPushState: false
}
btf.addGlobalFn('pjaxSend', () => {
Pace.restart()
}, 'pace_restart')
link(rel="stylesheet", href=url_for(theme.preloader.pace_css_url || theme.asset.pace_default_css))
script(src=url_for(theme.asset.pace_js))

View File

@@ -1,17 +1,20 @@
mixin articleSort(posts) mixin articleSort(posts)
.article-sort .article-sort
- var year - let year
- posts.each(function (article) { - posts.forEach(article => {
- let tempYear = date(article.date, 'YYYY') - const tempYear = date(article.date, 'YYYY')
- let no_cover = article.cover === false || !theme.cover.archives_enable ? 'no-article-cover' : '' - const noCoverClass = article.cover === false || !theme.cover.archives_enable ? 'no-article-cover' : ''
- let title = article.title || _p('no_title') - const title = article.title || _p('no_title')
if tempYear !== year if tempYear !== year
- year = tempYear - year = tempYear
.article-sort-item.year= year .article-sort-item.year= year
.article-sort-item(class=no_cover) .article-sort-item(class=noCoverClass)
if article.cover && theme.cover.archives_enable if article.cover && theme.cover.archives_enable
a.article-sort-item-img(href=url_for(article.path) title=title) a.article-sort-item-img(href=url_for(article.path) title=title)
if article.cover_type === 'img'
img(src=url_for(article.cover) alt=title onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'`) img(src=url_for(article.cover) alt=title onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'`)
else
div(style=`background: ${article.cover}`)
.article-sort-item-info .article-sort-item-info
.article-sort-item-time .article-sort-item-time
i.far.fa-calendar-alt i.far.fa-calendar-alt

View File

@@ -0,0 +1,122 @@
mixin indexPostUI()
- const indexLayout = theme.index_layout
- const masonryLayoutClass = (indexLayout === 6 || indexLayout === 7) ? 'masonry' : ''
#recent-posts.recent-posts.nc(class=masonryLayoutClass)
.recent-post-items
each article, index in page.posts.data
.recent-post-item
- const link = article.link || article.path
- const title = article.title || _p('no_title')
- const leftOrRight = indexLayout === 3 ? (index % 2 === 0 ? 'left' : 'right') : (indexLayout === 2 ? 'right' : '')
- const post_cover = article.cover
- const no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
if post_cover && theme.cover.index_enable
.post_cover(class=leftOrRight)
a(href=url_for(link) title=title)
if article.cover_type === 'img'
img.post-bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
else
div.post-bg(style=`background: ${post_cover}`)
.recent-post-info(class=no_cover)
a.article-title(href=url_for(link) title=title)
if is_home() && (article.top || article.sticky > 0)
i.fas.fa-thumbtack.sticky
= title
.article-meta-wrap
if theme.post_meta.page.date_type
span.post-meta-date
if theme.post_meta.page.date_type === 'both'
i.far.fa-calendar-alt
span.article-meta-label=_p('post.created')
time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))= date(article.date, config.date_format)
span.article-meta-separator |
i.fas.fa-history
span.article-meta-label=_p('post.updated')
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))= date(article.updated, config.date_format)
else
- const data_type_updated = theme.post_meta.page.date_type === 'updated'
- const date_type = data_type_updated ? 'updated' : 'date'
- const date_icon = data_type_updated ? 'fas fa-history' : 'far fa-calendar-alt'
- const date_title = data_type_updated ? _p('post.updated') : _p('post.created')
i(class=date_icon)
span.article-meta-label= date_title
time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))= date(article[date_type], config.date_format)
if theme.post_meta.page.categories && article.categories.data.length > 0
span.article-meta
span.article-meta-separator |
each item, index in article.categories.data
i.fas.fa-inbox
a(href=url_for(item.path)).article-meta__categories #[=item.name]
if index < article.categories.data.length - 1
i.fas.fa-angle-right.article-meta-link
if theme.post_meta.page.tags && article.tags.length > 0
span.article-meta.tags
span.article-meta-separator |
each item, index in article.tags.data
i.fas.fa-tag
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if index < article.tags.data.length - 1
span.article-meta-link #[='•']
mixin countBlockInIndex
- needLoadCountJs = true
span.article-meta
span.article-meta-separator |
i.fas.fa-comments
if block
block
span.article-meta-label= ' ' + _p('card_post_count')
if theme.comments.card_post_count && theme.comments.use
case theme.comments.use[0]
when 'Disqus'
when 'Disqusjs'
+countBlockInIndex
a.disqus-count(href=full_url_for(link) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Valine'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.valine-comment-count(data-xid=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Waline'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.waline-comment-count(data-path=url_for(link))
i.fa-solid.fa-spinner.fa-spin
when 'Twikoo'
+countBlockInIndex
a.twikoo-count(href=url_for(link) + '#post-comment')
i.fa-solid.fa-spinner.fa-spin
when 'Facebook Comments'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
when 'Remark42'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.remark42__counter(data-url=urlNoIndex(article.permalink))
i.fa-solid.fa-spinner.fa-spin
when 'Artalk'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.artalk-count(data-page-key=url_for(link))
i.fa-solid.fa-spinner.fa-spin
//- Display the article introduction on homepage
case theme.index_post_content.method
when false
- break
when 1
.content!= article.description
when 2
.content!= article.description || truncate(article.content, theme.index_post_content.length)
default
.content!= truncate(article.content, theme.index_post_content.length)
if theme.ad && theme.ad.index
if (index + 1) % 3 === 0
.recent-post-item.ads-wrap!= theme.ad.index
include ../pagination.pug

View File

@@ -1,114 +0,0 @@
mixin postUI(posts)
each article , index in page.posts.data
.recent-post-item
-
let link = article.link || article.path
let title = article.title || _p('no_title')
const position = theme.cover.position
let leftOrRight = position === 'both'
? index%2 == 0 ? 'left' : 'right'
: position === 'left' ? 'left' : 'right'
let post_cover = article.cover
let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
-
if post_cover && theme.cover.index_enable
.post_cover(class=leftOrRight)
a(href=url_for(link) title=title)
img.post_bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` alt=title)
.recent-post-info(class=no_cover)
a.article-title(href=url_for(link) title=title)= title
.article-meta-wrap
if (is_home() && (article.top || article.sticky > 0))
span.article-meta
i.fas.fa-thumbtack.sticky
span.sticky= _p('sticky')
span.article-meta-separator |
if (theme.post_meta.page.date_type)
span.post-meta-date
if (theme.post_meta.page.date_type === 'both')
i.far.fa-calendar-alt
span.article-meta-label=_p('post.created')
time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
span.article-meta-separator |
i.fas.fa-history
span.article-meta-label=_p('post.updated')
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
else
- let data_type_updated = theme.post_meta.page.date_type === 'updated'
- let date_type = data_type_updated ? 'updated' : 'date'
- let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
- let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
i(class=date_icon)
span.article-meta-label=date_title
time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
if (theme.post_meta.page.categories && article.categories.data.length > 0)
span.article-meta
span.article-meta-separator |
i.fas.fa-inbox
each item, index in article.categories.data
a(href=url_for(item.path)).article-meta__categories #[=item.name]
if (index < article.categories.data.length - 1)
i.fas.fa-angle-right.article-meta-link
if (theme.post_meta.page.tags && article.tags.data.length > 0)
span.article-meta.tags
span.article-meta-separator |
i.fas.fa-tag
each item, index in article.tags.data
a(href=url_for(item.path)).article-meta__tags #[=item.name]
if (index < article.tags.data.length - 1)
span.article-meta-link #[='•']
mixin countBlockInIndex
- needLoadCountJs = true
span.article-meta
span.article-meta-separator |
i.fas.fa-comments
if block
block
span.article-meta-label= ' ' + _p('card_post_count')
if theme.comments.card_post_count
case theme.comments.use[0]
when 'Disqus'
when 'Disqusjs'
+countBlockInIndex
a(href=full_url_for(link) + '#disqus_thread')
when 'Valine'
+countBlockInIndex
a(href=url_for(link) + '#post-comment' itemprop="discussionUrl")
span.valine-comment-count(data-xid=url_for(link) itemprop="commentCount")
when 'Waline'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.waline-comment-count(id=url_for(link))
when 'Twikoo'
+countBlockInIndex
a.twikoo-count(href=url_for(link) + '#post-comment')
when 'Facebook Comments'
+countBlockInIndex
a(href=url_for(link) + '#post-comment')
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
//- Display the article introduction on homepage
case theme.index_post_content.method
when false
- break
when 1
.content!= article.description
when 2
if article.description
.content!= article.description
else
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.content!= expert
default
- const content = strip_html(article.content)
- let expert = content.substring(0, theme.index_post_content.length)
- content.length > theme.index_post_content.length ? expert += ' ...' : ''
.content!= expert
if theme.ad && theme.ad.index
if (index + 1) % 3 == 0
.recent-post-item.ads-wrap!=theme.ad.index

View File

@@ -0,0 +1,8 @@
- var top_img_404 = theme.error_404.background || theme.default_top_img
.error-content
.error-img
img(src=url_for(top_img_404) alt='Page not found')
.error-info
h1.error_title= '404'
.error_subtitle= theme.error_404.subtitle || _p('error404')

View File

@@ -1,6 +1,10 @@
#article-container #article-container
.flink .flink
if page.flink_url - let { content, random, flink_url } = page
- let pageContent = content
if flink_url || random
- const linkData = flink_url ? false : site.data.link || false
script. script.
(()=>{ (()=>{
const replaceSymbol = (str) => { const replaceSymbol = (str) => {
@@ -8,9 +12,7 @@
} }
let result = "" let result = ""
fetch("!{url_for(page.flink_url)}") const add = (str) => {
.then(response => response.json())
.then(str => {
for(let i = 0; i < str.length; i++){ for(let i = 0; i < str.length; i++){
const replaceClassName = replaceSymbol(str[i].class_name) const replaceClassName = replaceSymbol(str[i].class_name)
const className = str[i].class_name ? `<h2 id="${replaceClassName}"><a href="#${replaceClassName}" class="headerlink" title="${str[i].class_name}"></a>${str[i].class_name}</h2>` : "" const className = str[i].class_name ? `<h2 id="${replaceClassName}"><a href="#${replaceClassName}" class="headerlink" title="${str[i].class_name}"></a>${str[i].class_name}</h2>` : ""
@@ -18,6 +20,9 @@
let listResult = "" let listResult = ""
const lists = str[i].link_list const lists = str[i].link_list
if (!{random === true}) {
lists.sort(() => Math.random() - 0.5)
}
for(let j = 0; j < lists.length; j++){ for(let j = 0; j < lists.length; j++){
listResult += ` listResult += `
<div class="flink-list-item"> <div class="flink-list-item">
@@ -35,7 +40,17 @@
} }
document.querySelector(".flink").insertAdjacentHTML("afterbegin", result) document.querySelector(".flink").insertAdjacentHTML("afterbegin", result)
}) window.lazyLoadInstance && window.lazyLoadInstance.update()
}
const linkData = !{JSON.stringify(linkData)}
if (!{Boolean(flink_url)}) {
fetch("!{url_for(flink_url)}")
.then(response => response.json())
.then(add)
} else if (linkData) {
add(linkData)
}
})() })()
else else
@@ -63,6 +78,5 @@
- result += `${className}${classDesc} <div class="flink-list">${listResult}</div>` - result += `${className}${classDesc} <div class="flink-list">${listResult}</div>`
- page.content = result + page.content - pageContent = result + pageContent
!= page.content != pageContent

View File

@@ -0,0 +1,103 @@
//- - author:
//- avatar:
//- date:
//- content:
//- tags:
//- - tag1
//- - tag2
- page.comments = false
- page.toc = false
#article-container
if page.shuoshuo_url
script.
(() => {
const loadShuoshuo = async () => {
try {
const fetchContent = await fetch('!{url_for(page.shuoshuo_url)}')
const shuoshuo = await fetchContent.json()
let start = 0
const container = document.getElementById('article-container')
const addData = data => {
const cLength = data.length
const end = start + 10 > cLength ? cLength : start + 10
let result = ''
data.slice(start, end).forEach((item) => {
result += `
<div class="shuoshuo-item">
<div class="shuoshuo-item-header">
<div class="shuoshuo-avatar">
<img class="no-lightbox" src="${item.avatar || '!{url_for(theme.avatar.img)}'}">
</div>
<div class="shuoshuo-info">
<div class="shuoshuo-author">${item.author || '!{config.author}'}</div>
<div class="shuoshuo-date">${btf.diffDate(item.date, true)}</div>
</div>
</div>
<div class="shuoshuo-content">
${item.content}
</div>
<div class="shuoshuo-footer">
<div class="shuoshuo-tags">
${item.tags.map(tag => `<span class="shuoshuo-tag">${tag}</span>`).join('')}
</div>
</div>
</div>
`
})
start = end
container.insertAdjacentHTML('beforeend', result)
if (start >= cLength) {
observer.disconnect()
} else {
setTimeout(() => observer.observe(container.lastElementChild), 100)
}
window.lazyLoadInstance.update()
btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)'))
}
addData(shuoshuo)
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
observer.unobserve(entries[0].target)
addData(shuoshuo)
}
}, {
root: null,
rootMargin: '0px',
threshold: 1.0
})
if (container.lastElementChild) {
observer.observe(container.lastElementChild)
}
} catch (e) {
console.error(e)
}
}
window.pjax ? loadShuoshuo() : window.addEventListener('load', loadShuoshuo)
})()
else
if site.data.shuoshuo
each i in site.data.shuoshuo
.shuoshuo-item
.shuoshuo-item-header
.shuoshuo-avatar
img.no-lightbox(src=i.avatar || url_for(theme.avatar.img))
.shuoshuo-info
.shuoshuo-author=i.author || config.author
.shuoshuo-date=relative_date(i.date)
.shuoshuo-content
!=markdown(i.content)
.shuoshuo-footer
.shuoshuo-tags
each tag in i.tags
span.shuoshuo-tag=tag

View File

@@ -1,2 +1,2 @@
.tag-cloud-list.is-center .tag-cloud-list.is-center
!=cloudTags({source: site.tags, minfontsize: 1.2, maxfontsize: 2.1, limit: 0, unit: 'em'}) !=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 1.5, limit: 0, unit: 'em'})

View File

@@ -12,20 +12,22 @@ if is_post()
nav#pagination.pagination-post nav#pagination.pagination-post
if(prev) if(prev)
- var hasPageNext = next ? 'pull-left' : 'pull-full' - var hasPageNext = next ? 'pull-left' : 'pull-full'
.prev-post(class=hasPageNext) a.prev-post(class=hasPageNext href=url_for(prev.path) title=prev.title)
- var pagination_cover = prev.cover === false ? prev.randomcover : prev.cover if prev.cover_type === 'img'
a(href=url_for(prev.path)) img.cover(src=url_for(prev.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of previous post')
img.prev-cover(src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of previous post') else
.cover(style=`background: ${prev.cover || 'var(--default-bg-color)'}`)
.pagination-info .pagination-info
.label=_p('pagination.prev') .label=_p('pagination.prev')
.prev_info=prev.title .prev_info=prev.title
if(next) if(next)
- var hasPagePrev = prev ? 'pull-right' : 'pull-full' - var hasPagePrev = prev ? 'pull-right' : 'pull-full'
- var pagination_cover = next.cover == false ? next.randomcover : next.cover a.next-post(class=hasPagePrev href=url_for(next.path) title=next.title)
.next-post(class=hasPagePrev) if next.cover_type === 'img'
a(href=url_for(next.path)) img.cover(src=url_for(next.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of next post')
img.next-cover(src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of next post') else
.cover(style=`background: ${next.cover || 'var(--default-bg-color)'}`)
.pagination-info .pagination-info
.label=_p('pagination.next') .label=_p('pagination.next')
.next_info=next.title .next_info=next.title

View File

@@ -1,17 +1,23 @@
if theme.post_copyright.enable && page.copyright !== false if theme.post_copyright.enable && page.copyright !== false
- let author = page.copyright_author || config.author - const author = page.copyright_author || config.author
- let authorHref = page.copyright_author_href || theme.post_copyright.author_href || config.url - const authorHref = page.copyright_author_href || theme.post_copyright.author_href || config.url
- let url = page.copyright_url || page.permalink - const url = page.copyright_url || page.permalink
- let info = page.copyright_info || _p('post.copyright.copyright_content', theme.post_copyright.license_url, theme.post_copyright.license, config.url, config.title) - const info = page.copyright_info || _p('post.copyright.copyright_content', theme.post_copyright.license_url, theme.post_copyright.license, config.url, config.title)
.post-copyright .post-copyright
.post-copyright__author .post-copyright__author
span.post-copyright-meta= _p('post.copyright.author') + ": " span.post-copyright-meta
i.fas.fa-circle-user.fa-fw
= _p('post.copyright.author') + ": "
span.post-copyright-info span.post-copyright-info
a(href=authorHref)= author a(href=authorHref)= author
.post-copyright__type .post-copyright__type
span.post-copyright-meta= _p('post.copyright.link') + ": " span.post-copyright-meta
i.fas.fa-square-arrow-up-right.fa-fw
= _p('post.copyright.link') + ": "
span.post-copyright-info span.post-copyright-info
a(href=url_for(url))= theme.post_copyright.decode ? decodeURI(url) : url a(href=url_for(url))= theme.post_copyright.decode ? decodeURI(url) : url
.post-copyright__notice .post-copyright__notice
span.post-copyright-meta= _p('post.copyright.copyright_notice') + ": " span.post-copyright-meta
i.fas.fa-circle-exclamation.fa-fw
= _p('post.copyright.copyright_notice') + ": "
span.post-copyright-info!= info span.post-copyright-info!= info

View File

@@ -1,13 +1,12 @@
.post-reward .post-reward
.reward-button .reward-button
i.fas.fa-qrcode i.fas.fa-qrcode
= ' ' + _p('donate') = theme.reward.text || _p('donate')
.reward-main .reward-main
ul.reward-all ul.reward-all
each item in theme.reward.QR_code each item in theme.reward.QR_code
- var clickTo = item.link ? item.link : item.img - const clickTo = item.link || item.img
li.reward-item li.reward-item
a(href=url_for(clickTo) target='_blank') a(href=url_for(clickTo) target='_blank')
img.post-qr-code-img(src=url_for(item.img) alt=item.text) img.post-qr-code-img(src=url_for(item.img) alt=item.text)
.post-qr-code-desc=item.text .post-qr-code-desc=item.text

View File

@@ -1,4 +1,4 @@
- const { readmode, translate, darkmode, aside, chat_btn } = theme - const { readmode, translate, darkmode, aside, chat } = theme
mixin rightsideItem(array) mixin rightsideItem(array)
each item in array each item in array
case item case item
@@ -22,9 +22,9 @@ mixin rightsideItem(array)
button#mobile-toc-button.close(type="button" title=_p("rightside.toc")) button#mobile-toc-button.close(type="button" title=_p("rightside.toc"))
i.fas.fa-list-ul i.fas.fa-list-ul
when 'chat' when 'chat'
if chat_btn if chat.rightside_button && chat.use
button#chat_btn(type="button" title=_p("rightside.chat")) button#chat-btn(type="button" title=_p("rightside.chat"))
i.fas.fa-sms i.fas.fa-message
when 'comment' when 'comment'
if commentsJsLoad if commentsJsLoad
a#to_comment(href="#post-comment" title=_p("rightside.scroll_to_comment")) a#to_comment(href="#post-comment" title=_p("rightside.scroll_to_comment"))
@@ -42,19 +42,20 @@ mixin rightsideItem(array)
#rightside-config-show #rightside-config-show
if enable if enable
if hide if hide
button#rightside_config(type="button" title=_p("rightside.setting")) button#rightside-config(type="button" title=_p("rightside.setting"))
i.fas.fa-cog.fa-spin i.fas.fa-cog.fa-spin
else else
if is_post() if is_post()
if (readmode || translate.enable || (darkmode.enable && darkmode.button)) if (readmode || translate.enable || (darkmode.enable && darkmode.button))
button#rightside_config(type="button" title=_p("rightside.setting")) button#rightside-config(type="button" title=_p("rightside.setting"))
i.fas.fa-cog.fa-spin i.fas.fa-cog.fa-spin
else if translate.enable || (darkmode.enable && darkmode.button) else if translate.enable || (darkmode.enable && darkmode.button)
button#rightside_config(type="button" title=_p("rightside.setting")) button#rightside-config(type="button" title=_p("rightside.setting"))
i.fas.fa-cog.fa-spin i.fas.fa-cog.fa-spin
if showArray if showArray
+rightsideItem(showArray) +rightsideItem(showArray)
button#go-up(type="button" title=_p("rightside.back_to_top")) button#go-up(type="button" title=_p("rightside.back_to_top"))
span.scroll-percent
i.fas.fa-arrow-up i.fas.fa-arrow-up

View File

@@ -1,9 +1,10 @@
if theme.menu
#sidebar #sidebar
#menu-mask #menu-mask
#sidebar-menus #sidebar-menus
.avatar-img.is-center .avatar-img.is-center
img(src=url_for(theme.avatar.img) onerror=`onerror=null;src='${theme.error_img.flink}'` alt="avatar") img(src=url_for(theme.avatar.img) onerror=`onerror=null;src='${theme.error_img.flink}'` alt="avatar")
.sidebar-site-data.site-data.is-center .site-data.is-center
a(href=url_for(config.archive_dir) + '/') a(href=url_for(config.archive_dir) + '/')
.headline= _p('aside.articles') .headline= _p('aside.articles')
.length-num= site.posts.length .length-num= site.posts.length
@@ -14,5 +15,4 @@
.headline= _p('aside.categories') .headline= _p('aside.categories')
.length-num= site.categories.length .length-num= site.categories.length
hr
!=partial('includes/header/menu_item', {}, {cache: true}) !=partial('includes/header/menu_item', {}, {cache: true})

View File

@@ -0,0 +1,17 @@
script.
(() => {
const abcjsInit = () => {
const abcjsFn = () => {
document.querySelectorAll(".abc-music-sheet").forEach(ele => {
if (ele.children.length > 0) return
ABCJS.renderAbc(ele, ele.innerHTML, {responsive: 'resize'})
})
}
typeof ABCJS === 'object' ? abcjsFn()
: btf.getScript('!{url_for(theme.asset.abcjs_basic_js)}').then(abcjsFn)
}
window.pjax ? abcjsInit() : window.addEventListener('load', abcjsInit)
btf.addGlobalFn('encrypt', abcjsInit, 'abcjs')
})()

View File

@@ -0,0 +1,6 @@
if theme.abcjs.enable
if theme.abcjs.per_page
if is_post() || is_page()
include ./abcjs.pug
else if page.abcjs
include ./abcjs.pug

View File

@@ -1,3 +1,23 @@
link(rel='stylesheet' href=url_for(theme.asset.aplayer_css) media="print" onload="this.media='all'") link(rel='stylesheet' href=url_for(theme.asset.aplayer_css) media="print" onload="this.media='all'")
script(src=url_for(theme.asset.aplayer_js)) script(src=url_for(theme.asset.aplayer_js))
script(src=url_for(theme.asset.meting_js)) script(src=url_for(theme.asset.meting_js))
if theme.pjax.enable
script.
(() => {
const destroyAplayer = () => {
if (window.aplayers) {
for (let i = 0; i < window.aplayers.length; i++) {
if (!window.aplayers[i].options.fixed) {
window.aplayers[i].destroy()
}
}
}
}
const runMetingJS = () => {
typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()
}
btf.addGlobalFn('pjaxSend', destroyAplayer, 'destroyAplayer')
btf.addGlobalFn('pjaxComplete', loadMeting, 'runMetingJS')
})()

View File

@@ -0,0 +1,31 @@
- const { server, site } = theme.artalk
script.
(() => {
const getArtalkCount = async() => {
try {
const eleGroup = document.querySelectorAll('#recent-posts .artalk-count')
const keyArray = Array.from(eleGroup).map(i => i.getAttribute('data-page-key'))
const headerList = {
method: 'GET',
}
const searchParams = new URLSearchParams({
'site_name': '!{site}',
'page_keys': keyArray
})
const res = await fetch(`!{server}/api/v2/stats/page_comment?${searchParams}`, headerList)
const result = await res.json()
keyArray.forEach((key, index) => {
eleGroup[index].textContent = result.data[key] || 0
})
} catch (err) {
console.error(err)
}
}
window.pjax ? getArtalkCount() : window.addEventListener('load', getArtalkCount)
})()

View File

@@ -1,16 +1,25 @@
- const { shortname, apikey } = theme.disqus
script. script.
(() => { (() => {
const getCount = () => { const getCount = async () => {
if (window.DISQUSWIDGETS === undefined) { try {
var d = document, s = d.createElement('script'); const eleGroup = document.querySelectorAll('#recent-posts .disqus-count')
s.src = 'https://!{theme.disqus.shortname}.disqus.com/count.js'; const cleanedLinks = Array.from(eleGroup).map(i => `thread:link=${i.href.replace(/#post-comment$/, '')}`);
s.id = 'dsq-count-scr';
(d.head || d.body).appendChild(s); const res = await fetch(`https://disqus.com/api/3.0/threads/set.json?forum=!{shortname}&api_key=!{apikey}&${cleanedLinks.join('&')}`,{
} else { method: 'GET'
DISQUSWIDGETS.getCount({reset: true}); })
const result = await res.json()
eleGroup.forEach(i => {
const cleanedLink = i.href.replace(/#post-comment$/, '')
const urlData = result.response.find(data => data.link === cleanedLink) || { posts: 0 }
i.textContent = urlData.posts
})
} catch (err) {
console.error(err)
} }
} }
window.pjax ? getCount() : window.addEventListener('load', getCount) window.pjax ? getCount() : window.addEventListener('load', getCount)
})() })()

View File

@@ -1,10 +1,13 @@
- const fbSDKVer = 'v20.0'
- const fbSDK = `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
script. script.
(()=>{ (()=>{
function loadFBComment () { function loadFBComment () {
if (typeof FB === 'object') FB.XFBML.parse() if (typeof FB === 'object') FB.XFBML.parse(document.getElementById('recent-posts'))
else { else {
let ele = document.createElement('script') let ele = document.createElement('script')
ele.setAttribute('src','https://connect.facebook.net/!{theme.facebook_comments.lang}/sdk.js#xfbml=1&version=v9.0') ele.setAttribute('src','!{fbSDK}')
ele.setAttribute('async', 'true') ele.setAttribute('async', 'true')
ele.setAttribute('defer', 'true') ele.setAttribute('defer', 'true')
ele.setAttribute('crossorigin', 'anonymous') ele.setAttribute('crossorigin', 'anonymous')

View File

@@ -10,3 +10,7 @@ case theme.comments.use[0]
include ./waline.pug include ./waline.pug
when 'Facebook Comments' when 'Facebook Comments'
include ./fb.pug include ./fb.pug
when 'Remark42'
include ./remark42.pug
when 'Artalk'
include ./artalk.pug

View File

@@ -0,0 +1,18 @@
- const { host, siteId, option } = theme.remark42
script.
(()=>{
window.remark_config = Object.assign({
host: '!{host}',
site_id: '!{siteId}',
},!{JSON.stringify(option)})
function getCount () {
const s = document.createElement('script')
s.src = remark_config.host + '/web/counter.js'
s.defer = true
document.head.appendChild(s)
}
window.pjax ? getCount() : window.addEventListener('load', getCount)
})()

View File

@@ -18,7 +18,7 @@ script.
includeReply: false includeReply: false
}).then(function (res) { }).then(function (res) {
document.querySelectorAll('#recent-posts .twikoo-count').forEach((item,index) => { document.querySelectorAll('#recent-posts .twikoo-count').forEach((item,index) => {
item.innerText = res[index].count item.textContent = res[index].count
}) })
}).catch(function (err) { }).catch(function (err) {
console.log(err) console.log(err)
@@ -28,7 +28,7 @@ script.
if (typeof twikoo === 'object') { if (typeof twikoo === 'object') {
runTwikoo() runTwikoo()
} else { } else {
getScript('!{theme.asset.twikoo}').then(runTwikoo) btf.getScript('!{url_for(theme.asset.twikoo)}').then(runTwikoo)
} }
} }

View File

@@ -6,13 +6,14 @@ script.
el: '#vcomment', el: '#vcomment',
appId: '#{theme.valine.appId}', appId: '#{theme.valine.appId}',
appKey: '#{theme.valine.appKey}', appKey: '#{theme.valine.appKey}',
serverURLs: '#{theme.valine.serverURLs}'
} }
const valine = new Valine(initData) const valine = new Valine(initData)
} }
if (typeof Valine === 'function') initValine() if (typeof Valine === 'function') initValine()
else getScript('!{url_for(theme.asset.valine)}').then(initValine) else btf.getScript('!{url_for(theme.asset.valine)}').then(initValine)
} }
window.pjax ? loadValine() : window.addEventListener('load', loadValine) window.pjax ? loadValine() : window.addEventListener('load', loadValine)

View File

@@ -1,17 +1,20 @@
- const serverURL = theme.waline.serverURL.replace(/\/$/, '')
script. script.
(() => { (() => {
function loadWaline () { async function loadWaline () {
function initWaline () { try {
let initData = { const eleGroup = document.querySelectorAll('#recent-posts .waline-comment-count')
el: null, const keyArray = Array.from(eleGroup).map(i => i.getAttribute('data-path'))
serverURL: '!{theme.waline.serverURL}',
comment: true
}
const waline = Waline.init(initData)
}
if (typeof Waline === 'function') initWaline() const res = await fetch(`!{serverURL}/api/comment?type=count&url=${keyArray}`, { method: 'GET' })
else getScript('!{url_for(theme.asset.waline_js)}').then(initWaline) const result = await res.json()
result.data.forEach((count, index) => {
eleGroup[index].textContent = count
})
} catch (err) {
console.error(err)
}
} }
window.pjax ? loadWaline() : window.addEventListener('load', loadWaline) window.pjax ? loadWaline() : window.addEventListener('load', loadWaline)

View File

@@ -1,33 +1,42 @@
//- https://chatra.io/help/api/ //- https://chatra.io/help/api/
script. script.
(function(d, w, c) { (() => {
w.ChatraID = '#{theme.chatra.id}'; const isChatBtn = !{theme.chat.rightside_button}
var s = d.createElement('script'); const isChatHideShow = !{theme.chat.button_hide_show}
w[c] = w[c] || function() {
(w[c].q = w[c].q || []).push(arguments);
};
s.async = true;
s.src = 'https://call.chatra.io/chatra.js';
if (d.head) d.head.appendChild(s);
})(document, window, 'Chatra');
if (!{theme.chat_btn}) { if (isChatBtn) {
var chatBtnFn = () => { const close = () => {
var chatBtn = document.getElementById("chat_btn") Chatra('minimizeWidget')
chatBtn.addEventListener("click", function(){
Chatra('openChat')
});
}
chatBtnFn()
} else {
if (!{theme.chat_hide_show}) {
function chatBtnHide () {
Chatra('hide') Chatra('hide')
} }
function chatBtnShow () {
const open = () => {
Chatra('openChat', true)
Chatra('show') Chatra('show')
} }
window.ChatraSetup = { startHidden: true }
window.chatBtnFn = () => {
document.getElementById('chatra').classList.contains('chatra--expanded') ? close() : open()
}
} else if (isChatHideShow) {
window.chatBtn = {
hide: () => Chatra('hide'),
show: () => Chatra('show')
} }
} }
(function(d, w, c) {
w.ChatraID = '#{theme.chatra.id}'
var s = d.createElement('script')
w[c] = w[c] || function() {
(w[c].q = w[c].q || []).push(arguments)
}
s.async = true
s.src = 'https://call.chatra.io/chatra.js'
if (d.head) d.head.appendChild(s)
})(document, window, 'Chatra')
})()

View File

@@ -1,4 +1,5 @@
script. script.
(() => {
window.$crisp = []; window.$crisp = [];
window.CRISP_WEBSITE_ID = "!{theme.crisp.website_id}"; window.CRISP_WEBSITE_ID = "!{theme.crisp.website_id}";
(function () { (function () {
@@ -10,27 +11,27 @@ script.
})(); })();
$crisp.push(["safe", true]) $crisp.push(["safe", true])
if (!{theme.chat_btn}) { const isChatBtn = !{theme.chat.rightside_button}
$crisp.push(["do", "chat:hide"]) const isChatHideShow = !{theme.chat.button_hide_show}
$crisp.push(["on", "chat:closed", function() {
$crisp.push(["do", "chat:hide"]) if (isChatBtn) {
}]) const open = () => {
var chatBtnFn = () => {
var chatBtn = document.getElementById("chat_btn")
chatBtn.addEventListener("click", function(){
$crisp.push(["do", "chat:show"]) $crisp.push(["do", "chat:show"])
$crisp.push(["do", "chat:open"]) $crisp.push(["do", "chat:open"])
}
}); const close = () => $crisp.push(["do", "chat:hide"])
}
chatBtnFn() close()
} else {
if (!{theme.chat_hide_show}) { $crisp.push(["on", "chat:closed", close])
function chatBtnHide () {
$crisp.push(["do", "chat:hide"]) window.chatBtnFn = () => $crisp.is("chat:visible") ? close() : open()
}
function chatBtnShow () { } else if (isChatHideShow) {
$crisp.push(["do", "chat:show"]) window.chatBtn = {
} hide: () => $crisp.push(["do", "chat:hide"]),
show: () => $crisp.push(["do", "chat:show"])
} }
} }
})()

View File

@@ -1,40 +1,40 @@
//- https://guide.daocloud.io/daovoice/javascript-api-5869833.html //- https://guide.daocloud.io/daovoice/javascript-api-5869833.html
script. script.
(() => {
(function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/!{theme.daovoice.app_id}.js","daovoice") (function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/!{theme.daovoice.app_id}.js","daovoice")
script. const isChatBtn = !{theme.chat.rightside_button}
var isChatBtn = !{theme.chat_btn} const isChatHideShow = !{theme.chat.button_hide_show}
daovoice('init', { daovoice('init', {
app_id: '!{theme.daovoice.app_id}',},{ app_id: '!{theme.daovoice.app_id}',},{
launcher: { launcher: {
disableLauncherIcon: isChatBtn // 悬浮 ICON 是否显示 disableLauncherIcon: isChatBtn
}, },
}); });
daovoice('update'); daovoice('update');
if (isChatBtn) { if (isChatBtn) {
var chatBtnFn = () => { window.chatBtnFn = () => {
var chatBtn = document.getElementById("chat_btn") const isShow = document.getElementById('daodream-messenger').classList.contains('daodream-messenger-active')
chatBtn.addEventListener("click", function(){ isShow ? daovoice('hide') : daovoice('show')
daovoice('show')
});
} }
chatBtnFn() } else if (isChatHideShow) {
} else { window.chatBtn = {
if (!{theme.chat_hide_show}) { hide: () => {
function chatBtnHide () {
daovoice('update', {},{ daovoice('update', {},{
launcher: { launcher: {
disableLauncherIcon: true // 悬浮 ICON 是否显示 disableLauncherIcon: true
},
});
} }
function chatBtnShow () { })
},
show: () => {
daovoice('update', {}, { daovoice('update', {}, {
launcher: { launcher: {
disableLauncherIcon: false // 悬浮 ICON 是否显示 disableLauncherIcon: false
}, }
}); })
} }
} }
} }
})()

View File

@@ -1,43 +0,0 @@
if theme.chat_btn
script.
((window.gitter = {}).chat = {}).options = {
disableDefaultChat: true,
};
document.addEventListener('gitter-sidecar-ready', (e) => {
const GitterChat = e.detail.Chat
let chat
function initGitter () {
chat = new GitterChat({
room: '#{theme.gitter.room}',
activationElement: '#chat_btn'
});
}
initGitter()
if (!{theme.pjax.enable}) {
document.addEventListener('pjax:complete', () => {
chat.destroy()
initGitter()
})
}
})
else
script.
((window.gitter = {}).chat = {}).options = {
room: '#{theme.gitter.room}',
};
if (!{theme.chat_hide_show}) {
function chatBtnHide () {
document.getElementsByClassName('gitter-open-chat-button')[0].style.display= 'none'
}
function chatBtnShow () {
document.getElementsByClassName('gitter-open-chat-button')[0].style.display= 'block'
}
}
script(src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer)

View File

@@ -1,10 +1,9 @@
if theme.chatra && theme.chatra.enable case theme.chat.use
when 'chatra'
include ./chatra.pug include ./chatra.pug
else if theme.tidio && theme.tidio.enable when 'tidio'
include ./tidio.pug include ./tidio.pug
else if theme.daovoice && theme.daovoice.enable when 'daovoice'
include ./daovoice.pug include ./daovoice.pug
else if theme.gitter && theme.gitter.enable when 'crisp'
include ./gitter.pug
else if theme.crisp && theme.crisp.enable
include ./crisp.pug include ./crisp.pug

View File

@@ -1,41 +1,41 @@
script(src=`//code.tidio.co/${theme.tidio.public_key}.js` async) script(src=`//code.tidio.co/${theme.tidio.public_key}.js` async)
if theme.chat_btn
script. script.
function onTidioChatApiReady() { (() => {
window.tidioChatApi.hide(); const isChatBtn = !{theme.chat.rightside_button}
window.tidioChatApi.on("close", function() { const isChatHideShow = !{theme.chat.button_hide_show}
window.tidioChatApi.hide();
}); if (isChatBtn) {
let isShow = false
const close = () => {
window.tidioChatApi.hide()
isShow = false
}
const open = () => {
window.tidioChatApi.open()
window.tidioChatApi.show()
isShow = true
}
const onTidioChatApiReady = () => {
window.tidioChatApi.hide()
window.tidioChatApi.on("close", close)
} }
if (window.tidioChatApi) { if (window.tidioChatApi) {
window.tidioChatApi.on("ready", onTidioChatApiReady); window.tidioChatApi.on("ready", onTidioChatApiReady)
} else { } else {
document.addEventListener("tidioChat-ready", onTidioChatApiReady); document.addEventListener("tidioChat-ready", onTidioChatApiReady)
} }
var chatBtnFn = () => { window.chatBtnFn = () => {
document.getElementById("chat_btn").addEventListener("click", function(){ if (!window.tidioChatApi) return
window.tidioChatApi.show(); isShow ? close() : open()
window.tidioChatApi.open();
});
} }
chatBtnFn() } else if (isChatHideShow) {
window.chatBtn = {
else if theme.chat_hide_show hide: () => window.tidioChatApi && window.tidioChatApi.hide(),
script. show: () => window.tidioChatApi && window.tidioChatApi.show()
function chatBtnHide () { }
if (window.tidioChatApi) { }
//- window.tidioChatApi.hide(); })()
document.getElementById('tidio-chat').style.display= 'none'
}
}
function chatBtnShow () {
if (window.tidioChatApi) {
//- window.tidioChatApi.show();
document.getElementById('tidio-chat').style.display= 'block'
}
}

View File

@@ -0,0 +1,55 @@
- const { server, site, option } = theme.artalk
- const { use, lazyload } = theme.comments
script.
(() => {
let artalkItem = null
const initArtalk = () => {
artalkItem = Artalk.init(Object.assign({
el: '#artalk-wrap',
server: '!{server}',
site: '!{site}',
pageKey: location.pathname,
darkMode: document.documentElement.getAttribute('data-theme') === 'dark',
},!{JSON.stringify(option)}))
if (GLOBAL_CONFIG.lightbox === 'null') return
artalkItem.on('list-loaded', () => {
artalkItem.ctx.get('list').getCommentNodes().forEach(comment => {
const $content = comment.getRender().$content
btf.loadLightbox($content.querySelectorAll('img:not([atk-emoticon])'))
})
})
const destroyArtalk = () => {
artalkItem.destroy()
}
btf.addGlobalFn('pjaxSendOnce', destroyArtalk, 'destroyArtalk')
}
const loadArtalk = async () => {
if (typeof Artalk === 'object') initArtalk()
else {
await btf.getCSS('!{theme.asset.artalk_css}')
await btf.getScript('!{theme.asset.artalk_js}')
initArtalk()
}
}
const artalkChangeMode = theme => {
const artalkWrap = document.getElementById('artalk-wrap')
if (!(artalkWrap && artalkWrap.children.length)) return
const isDark = theme === 'dark'
artalkItem.setDarkMode(isDark)
}
btf.addGlobalFn('themeChange', artalkChangeMode, 'artalk')
if ('!{use[0]}' === 'Artalk' || !!{lazyload}) {
if (!{lazyload}) btf.loadComment(document.getElementById('artalk-wrap'), loadArtalk)
else setTimeout(loadArtalk, 100)
} else {
window.loadOtherComment = loadArtalk
}
})()

View File

@@ -1,47 +1,59 @@
- let disqusPageTitle = page.title.replace(/'/ig,"\\'") - const disqusPageTitle = page.title.replace(/'/ig,"\\'")
- const { shortname, apikey } = theme.disqus
- const { use, lazyload, count } = theme.comments
script. script.
function loadDisqus () { (() => {
var disqus_config = function () { const disqus_config = function () {
this.page.url = '!{ page.permalink }' this.page.url = '!{ page.permalink }'
this.page.identifier = '!{ page.path }' this.page.identifier = '!{ url_for(page.path) }'
this.page.title = '!{ disqusPageTitle }' this.page.title = '!{ disqusPageTitle }'
}; }
window.disqusReset = () => { const disqusReset = () => {
DISQUS.reset({ window.DISQUS && window.DISQUS.reset({
reload: true, reload: true,
config: disqus_config config: disqus_config
}) })
} }
btf.addGlobalFn('themeChange', disqusReset, 'disqus')
const loadDisqus = () =>{
if (window.DISQUS) disqusReset() if (window.DISQUS) disqusReset()
else { else {
(function() { const script = document.createElement('script')
var d = document, s = d.createElement('script'); script.src = 'https://!{shortname}.disqus.com/embed.js'
s.src = 'https://!{theme.disqus.shortname}.disqus.com/embed.js'; script.setAttribute('data-timestamp', +new Date())
s.setAttribute('data-timestamp', +new Date()); document.head.appendChild(script)
(d.head || d.body).appendChild(s);
})();
} }
} }
if ('!{theme.comments.use[0]}' === 'Disqus' || !!{theme.comments.lazyload}) { const getCount = async() => {
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('disqus_thread'), loadDisqus) try {
else loadDisqus() const eleGroup = document.querySelector('#post-meta .disqus-comment-count')
} else { if (!eleGroup) return
function loadOtherComment () { const cleanedLinks = eleGroup.href.replace(/#post-comment$/, '')
const res = await fetch(`https://disqus.com/api/3.0/threads/set.json?forum=!{shortname}&api_key=!{apikey}&thread:link=${cleanedLinks}`,{
method: 'GET'
})
const result = await res.json()
const count = result.response.length ? result.response[0].posts : 0
eleGroup.textContent = count
} catch (err) {
console.error(err)
}
}
if ('!{use[0]}' === 'Disqus' || !!{lazyload}) {
if (!{lazyload}) btf.loadComment(document.getElementById('disqus_thread'), loadDisqus)
else {
loadDisqus() loadDisqus()
!{ count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : '' }
} }
}
if is_post() && !theme.comments.lazyload && theme.comments.count && theme.comments.use[0] === 'Disqus'
script.
if (window.DISQUSWIDGETS === undefined) {
var d = document, s = d.createElement('script');
s.src = 'https://!{theme.disqus.shortname}.disqus.com/count.js';
s.id = 'dsq-count-scr';
(d.head || d.body).appendChild(s);
} else { } else {
DISQUSWIDGETS.getCount({reset: true}); window.loadOtherComment = loadDisqus
} }
})()

View File

@@ -1,55 +1,64 @@
- let disqusjsPageTitle = page.title.replace(/'/ig,"\\'") - let disqusjsPageTitle = page.title.replace(/'/ig,"\\'")
- const { shortname:dqShortname, apikey:dqApikey, option:dqOption } = theme.disqusjs
script. script.
function loadDisqusjs () { (() => {
function addDisqusjsCSS () { const initDisqusjs = () => {
const ele = document.createElement('link') window.disqusjs = null
ele.rel = 'stylesheet' disqusjs = new DisqusJS(Object.assign({
ele.href= '!{url_for(theme.asset.disqusjs_css)}' shortname: '!{dqShortname}',
document.getElementsByTagName('head')[0].appendChild(ele) identifier: '!{ url_for(page.path) }',
}
function initDisqusjs () {
window.DISQUS = null
new DisqusJS(Object.assign({
shortname: '!{theme.disqusjs.shortname}',
identifier: '!{ page.path }',
url: '!{ page.permalink }', url: '!{ page.permalink }',
title: '!{ disqusjsPageTitle }', title: '!{ disqusjsPageTitle }',
apikey: '!{theme.disqusjs.apikey}', apikey: '!{dqApikey}',
},!{JSON.stringify(theme.disqusjs.option)})) },!{JSON.stringify(dqOption)}))
disqusjs.render(document.getElementById('disqusjs-wrap'))
} }
const themeChange = () => {
const ele = document.getElementById('disqus_thread')
if(!ele) return
disqusjs.destroy()
initDisqusjs()
}
window.disqusReset = initDisqusjs btf.addGlobalFn('themeChange', themeChange, 'disqusjs')
const loadDisqusjs = async() => {
if (window.disqusJsLoad) initDisqusjs() if (window.disqusJsLoad) initDisqusjs()
else { else {
addDisqusjsCSS() await btf.getCSS('!{url_for(theme.asset.disqusjs_css)}')
getScript('!{url_for(theme.asset.disqusjs)}').then(initDisqusjs) await btf.getScript('!{url_for(theme.asset.disqusjs)}')
initDisqusjs()
window.disqusJsLoad = true window.disqusJsLoad = true
} }
} }
const getCount = async() => {
try {
const eleGroup = document.querySelector('#post-meta .disqusjs-comment-count')
if (!eleGroup) return
const cleanedLinks = eleGroup.href.replace(/#post-comment$/, '')
const res = await fetch(`https://disqus.com/api/3.0/threads/set.json?forum=!{dqShortname}&api_key=!{dqApikey}&thread:link=${cleanedLinks}`,{
method: 'GET'
})
const result = await res.json()
const count = result.response.length ? result.response[0].posts : 0
eleGroup.textContent = count
} catch (err) {
console.error(err)
}
}
if ('!{theme.comments.use[0]}' === 'Disqusjs' || !!{theme.comments.lazyload}) { if ('!{theme.comments.use[0]}' === 'Disqusjs' || !!{theme.comments.lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('disqus_thread'), loadDisqusjs) if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('disqusjs-wrap'), loadDisqusjs)
else loadDisqusjs()
}
else { else {
function loadOtherComment () {
loadDisqusjs() loadDisqusjs()
!{ theme.comments.count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : '' }
} }
}
if is_post() && !theme.comments.lazyload && theme.comments.count && theme.comments.use[0] === 'Disqusjs'
script.
if (window.DISQUSWIDGETS === undefined) {
var d = document, s = d.createElement('script');
s.src = 'https://!{theme.disqus.shortname}.disqus.com/count.js';
s.id = 'dsq-count-scr';
(d.head || d.body).appendChild(s);
} else { } else {
DISQUSWIDGETS.getCount({reset: true}); window.loadOtherComment = loadDisqusjs
} }
})()

View File

@@ -1,26 +1,46 @@
#fb-root - const fbSDKVer = 'v20.0'
script. - const fbSDK = `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
function loadFBComment () {
var themeNow = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
document.getElementsByClassName('fb-comments')[0].setAttribute('data-colorscheme',themeNow)
if (typeof FB === 'object') FB.XFBML.parse() script.
(()=>{
const loadFBComment = () => {
document.getElementById('fb-root') ? '' : document.body.insertAdjacentHTML('afterend', '<div id="fb-root"></div>')
const themeNow = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
const $fbComment = document.getElementsByClassName('fb-comments')[0]
$fbComment.setAttribute('data-colorscheme',themeNow)
$fbComment.setAttribute('data-href', '!{urlNoIndex(page.permalink)}')
if (typeof FB === 'object') {
FB.XFBML.parse(document.getElementsByClassName('post-meta-commentcount')[0])
FB.XFBML.parse(document.getElementById('post-comment'))
}
else { else {
let ele = document.createElement('script') let ele = document.createElement('script')
ele.setAttribute('src','https://connect.facebook.net/!{theme.facebook_comments.lang}/sdk.js#xfbml=1&version=v13.0&appId=!{theme.facebook_comments.app_id}&autoLogAppEvents=1') ele.setAttribute('src','!{fbSDK}')
ele.setAttribute('async', 'true') ele.setAttribute('async', 'true')
ele.setAttribute('defer', 'true') ele.setAttribute('defer', 'true')
ele.setAttribute('crossorigin', 'anonymous') ele.setAttribute('crossorigin', 'anonymous')
ele.setAttribute('id', 'facebook-jssdk')
document.getElementById('fb-root').insertAdjacentElement('afterbegin',ele) document.getElementById('fb-root').insertAdjacentElement('afterbegin',ele)
} }
} }
const fbModeChange = theme => {
const $fbComment = document.getElementsByClassName('fb-comments')[0]
if ($fbComment && typeof FB === 'object') {
$fbComment.setAttribute('data-colorscheme',theme)
FB.XFBML.parse(document.getElementById('post-comment'))
}
}
btf.addGlobalFn('themeChange', fbModeChange, 'facebook_comments')
if ('!{theme.comments.use[0]}' === 'Facebook Comments' || !!{theme.comments.lazyload}) { if ('!{theme.comments.use[0]}' === 'Facebook Comments' || !!{theme.comments.lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.querySelector('#post-comment .fb-comments'), loadFBComment) if (!{theme.comments.lazyload}) btf.loadComment(document.querySelector('#post-comment .fb-comments'), loadFBComment)
else loadFBComment() else loadFBComment()
} else { } else {
function loadOtherComment () { window.loadOtherComment = loadFBComment
loadFBComment()
}
} }
})()

View File

@@ -1,49 +1,52 @@
- const { repo, repo_id, category_id, option } = theme.giscus - const { use, lazyload } = theme.comments
- const themes = theme.giscus.theme - const { repo, repo_id, category_id, light_theme, dark_theme, js, option } = theme.giscus
script. - const giscusUrl = js || 'https://giscus.app/client.js'
function loadGiscus () { - const giscusOriginUrl = new URL(giscusUrl).origin
let nowTheme = document.documentElement.getAttribute('data-theme') === 'dark' ? '!{themes.dark}' : '!{themes.light}'
script.
(()=>{
const getGiscusTheme = theme => theme === 'dark' ? '!{dark_theme}' : '!{light_theme}'
const loadGiscus = () => {
const config = Object.assign({ const config = Object.assign({
src: 'https://giscus.app/client.js', src: '!{giscusUrl}',
'data-repo': '!{repo}', 'data-repo': '!{repo}',
'data-repo-id': '!{repo_id}', 'data-repo-id': '!{repo_id}',
'data-category-id': '!{category_id}', 'data-category-id': '!{category_id}',
'data-mapping': 'pathname', 'data-mapping': 'pathname',
'data-theme': nowTheme, 'data-theme': getGiscusTheme(document.documentElement.getAttribute('data-theme')),
'data-reactions-enabled': '1', 'data-reactions-enabled': '1',
crossorigin: 'anonymous', crossorigin: 'anonymous',
async: true async: true
},!{JSON.stringify(option)}) },!{JSON.stringify(option)})
let ele = document.createElement('script') const ele = document.createElement('script')
for (let key in config) { for (let key in config) {
ele.setAttribute(key, config[key]) ele.setAttribute(key, config[key])
} }
document.getElementById('giscus-wrap').insertAdjacentElement('afterbegin',ele) document.getElementById('giscus-wrap').appendChild(ele)
} }
function changeGiscusTheme () { const changeGiscusTheme = theme => {
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? '!{themes.dark}' : '!{themes.light}' const iframe = document.querySelector('#giscus-wrap iframe')
if (iframe) {
function sendMessage(message) { const message = {
const iframe = document.querySelector('iframe.giscus-frame'); giscus: {
if (!iframe) return;
iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
}
sendMessage({
setConfig: { setConfig: {
theme: theme theme: getGiscusTheme(theme)
}
}
}
iframe.contentWindow.postMessage(message, '!{giscusOriginUrl}')
} }
});
} }
if ('!{theme.comments.use[0]}' === 'Giscus' || !!{theme.comments.lazyload}) { btf.addGlobalFn('themeChange', changeGiscusTheme, 'giscus')
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('giscus-wrap'), loadGiscus)
if ('!{use[0]}' === 'Giscus' || !!{lazyload}) {
if (!{lazyload}) btf.loadComment(document.getElementById('giscus-wrap'), loadGiscus)
else loadGiscus() else loadGiscus()
} else { } else {
function loadOtherComment () { window.loadOtherComment= loadGiscus
loadGiscus()
}
} }
})()

View File

@@ -1,37 +1,34 @@
script. - const { client_id, client_secret, repo, owner, admin, option } = theme.gitalk
function addGitalkSource () {
const ele = document.createElement('link')
ele.rel = 'stylesheet'
ele.href= '!{url_for(theme.asset.gitalk_css)}'
document.getElementsByTagName('head')[0].appendChild(ele)
}
function loadGitalk () { script.
function initGitalk () { (() => {
var gitalk = new Gitalk(Object.assign({ const initGitalk = () => {
clientID: '!{theme.gitalk.client_id}', const gitalk = new Gitalk(Object.assign({
clientSecret: '!{theme.gitalk.client_secret}', clientID: '!{client_id}',
repo: '!{theme.gitalk.repo}', clientSecret: '!{client_secret}',
owner: '!{theme.gitalk.owner}', repo: '!{repo}',
admin: ['!{theme.gitalk.admin}'], owner: '!{owner}',
admin: ['!{admin}'],
id: '!{md5(page.path)}', id: '!{md5(page.path)}',
updateCountCallback: commentCount updateCountCallback: commentCount
},!{JSON.stringify(theme.gitalk.option)})) },!{JSON.stringify(option)}))
gitalk.render('gitalk-container') gitalk.render('gitalk-container')
} }
const loadGitalk = async() => {
if (typeof Gitalk === 'function') initGitalk() if (typeof Gitalk === 'function') initGitalk()
else { else {
addGitalkSource() await btf.getCSS('!{url_for(theme.asset.gitalk_css)}')
getScript('!{url_for(theme.asset.gitalk)}').then(initGitalk) await btf.getScript('!{url_for(theme.asset.gitalk)}')
initGitalk()
} }
} }
function commentCount(n){ const commentCount = n => {
let isCommentCount = document.querySelector('#post-meta .gitalk-comment-count') const isCommentCount = document.querySelector('#post-meta .gitalk-comment-count')
if (isCommentCount) { if (isCommentCount) {
isCommentCount.innerHTML= n isCommentCount.textContent= n
} }
} }
@@ -39,10 +36,9 @@ script.
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('gitalk-container'), loadGitalk) if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('gitalk-container'), loadGitalk)
else loadGitalk() else loadGitalk()
} else { } else {
function loadOtherComment () { window.loadOtherComment = loadGitalk
loadGitalk()
}
} }
})()

View File

@@ -1,5 +1,5 @@
- let defaultComment = theme.comments.use[0] - let defaultComment = theme.comments.use[0]
hr hr.custom-hr
#post-comment #post-comment
.comment-head .comment-head
.comment-headline .comment-headline
@@ -7,9 +7,9 @@ hr
span= ' ' + _p('comment') span= ' ' + _p('comment')
if theme.comments.use.length > 1 if theme.comments.use.length > 1
#comment-switch .comment-switch
span.first-comment=defaultComment span.first-comment=defaultComment
span.switch-btn span#switch-btn
span.second-comment=theme.comments.use[1] span.second-comment=theme.comments.use[1]
@@ -22,7 +22,7 @@ hr
when 'Valine' when 'Valine'
#vcomment.vcomment #vcomment.vcomment
when 'Disqusjs' when 'Disqusjs'
#disqus_thread #disqusjs-wrap
when 'Livere' when 'Livere'
#lv-container(data-id="city" data-uid=theme.livere.uid) #lv-container(data-id="city" data-uid=theme.livere.uid)
when 'Gitalk' when 'Gitalk'
@@ -40,3 +40,7 @@ hr
data-numposts= theme.facebook_comments.pageSize || 10 data-numposts= theme.facebook_comments.pageSize || 10
data-order-by= theme.facebook_comments.order_by || 'social' data-order-by= theme.facebook_comments.order_by || 'social'
data-width="100%") data-width="100%")
when 'Remark42'
#remark42
when 'Artalk'
#artalk-wrap

View File

@@ -19,4 +19,8 @@ each name in theme.comments.use
when 'Giscus' when 'Giscus'
!=partial('includes/third-party/comments/giscus', {}, {cache: true}) !=partial('includes/third-party/comments/giscus', {}, {cache: true})
when 'Facebook Comments' when 'Facebook Comments'
!=partial('includes/third-party/comments/facebook_comments', {}, {cache: true}) include ./facebook_comments.pug
when 'Remark42'
!=partial('includes/third-party/comments/remark42', {}, {cache: true})
when 'Artalk'
!=partial('includes/third-party/comments/artalk', {}, {cache: true})

View File

@@ -1,8 +1,9 @@
- const { use, lazyload } = theme.comments
script. script.
function loadLivere () { (()=>{
if (typeof LivereTower === 'object') { const loadLivere = () => {
window.LivereTower.init() if (typeof LivereTower === 'object') window.LivereTower.init()
}
else { else {
(function(d, s) { (function(d, s) {
var j, e = d.getElementsByTagName(s)[0]; var j, e = d.getElementsByTagName(s)[0];
@@ -15,12 +16,10 @@ script.
} }
} }
if ('!{theme.comments.use[0]}' === 'Livere' || !!{theme.comments.lazyload}) { if ('!{use[0]}' === 'Livere' || !!{lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('lv-container'), loadLivere) if (!{lazyload}) btf.loadComment(document.getElementById('lv-container'), loadLivere)
else loadLivere() else loadLivere()
} else {
window.loadOtherComment = loadLivere
} }
else { })()
function loadOtherComment () {
loadLivere()
}
}

View File

@@ -0,0 +1,68 @@
- const { host, siteId, option } = theme.remark42
script.
var remark_config = Object.assign({
host: '!{host}',
site_id: '!{siteId}',
components: ['embed'],
theme: document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
},!{JSON.stringify(option)})
function addRemark42(){
for (let i = 0; i < remark_config.components.length; i++) {
const s = document.createElement('script')
s.src = remark_config.host + '/web/' + remark_config.components[i] + '.js'
s.defer = true
document.head.appendChild(s)
}
}
function initRemark42() {
if (window.REMARK42) {
if (this.remark42Instance) {
this.remark42Instance.destroy()
}
this.remark42Instance = window.REMARK42.createInstance({
...remark_config
})
}
}
function getCount () {
const ele = document.querySelector('.remark42__counter')
if (ele) {
const s = document.createElement('script')
s.src = remark_config.host + '/web/counter.js'
s.defer = true
document.head.appendChild(s)
}
}
function loadRemark42 () {
if (window.REMARK42) {
this.initRemark42()
getCount()
} else {
addRemark42()
window.addEventListener('REMARK42::ready', () => {
this.initRemark42()
getCount()
})
}
}
function remarkChangeMode (theme) {
if (!window.REMARK42) return
window.REMARK42.changeTheme(theme)
}
btf.addGlobalFn('themeChange', remarkChangeMode, 'remark42')
if ('!{theme.comments.use[0]}' === 'Remark42' || !!{theme.comments.lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('remark42'), loadRemark42)
else loadRemark42()
} else {
function loadOtherComment () {
loadRemark42()
}
}

View File

@@ -3,49 +3,43 @@
script. script.
(() => { (() => {
const init = () => {
twikoo.init(Object.assign({
el: '#twikoo-wrap',
envId: '!{envId}',
region: '!{region}',
onCommentLoaded: function () {
btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
}
}, !{JSON.stringify(option)}))
}
const getCount = () => { const getCount = () => {
const countELement = document.getElementById('twikoo-count')
if(!countELement) return
twikoo.getCommentsCount({ twikoo.getCommentsCount({
envId: '!{envId}', envId: '!{envId}',
region: '!{region}', region: '!{region}',
urls: [window.location.pathname], urls: [window.location.pathname],
includeReply: false includeReply: false
}).then(function (res) { }).then(res => {
document.getElementById('twikoo-count').innerText = res[0].count countELement.textContent = res[0].count
}).catch(function (err) { }).catch(err => {
console.error(err); console.error(err)
}); })
} }
const runFn = () => { const init = () => {
init() twikoo.init(Object.assign({
el: '#twikoo-wrap',
envId: '!{envId}',
region: '!{region}',
onCommentLoaded: () => {
btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
}
}, !{JSON.stringify(option)}))
!{count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : ''} !{count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : ''}
} }
const loadTwikoo = () => { const loadTwikoo = () => {
if (typeof twikoo === 'object') { if (typeof twikoo === 'object') setTimeout(init,0)
setTimeout(runFn,0) else btf.getScript('!{url_for(theme.asset.twikoo)}').then(init)
return
}
getScript('!{theme.asset.twikoo}').then(runFn)
} }
if ('!{use[0]}' === 'Twikoo' || !!{lazyload}) { if ('!{use[0]}' === 'Twikoo' || !!{lazyload}) {
if (!{lazyload}) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo) if (!{lazyload}) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo)
else loadTwikoo() else loadTwikoo()
} else { } else {
window.loadOtherComment = () => { window.loadOtherComment = loadTwikoo
loadTwikoo()
}
} }
})() })()

View File

@@ -1,34 +1,47 @@
- const { use, lazyload } = theme.comments
- const { repo, issue_term, light_theme, dark_theme, js, option } = theme.utterances
- const utterancesUrl = js || 'https://utteranc.es/client.js'
- const utterancesOriginUrl = new URL(utterancesUrl).origin
script. script.
function loadUtterances () { (() => {
let ele = document.createElement('script') const getUtterancesTheme = theme => theme === 'dark' ? '#{dark_theme}' : '#{light_theme}'
ele.setAttribute('id', 'utterances_comment')
ele.setAttribute('src', 'https://utteranc.es/client.js') const loadUtterances = () => {
ele.setAttribute('repo', '!{theme.utterances.repo}') const config = Object.assign({
ele.setAttribute('issue-term', '!{theme.utterances.issue_term}') id: 'utterances_comment',
let nowTheme = document.documentElement.getAttribute('data-theme') === 'dark' ? '#{theme.utterances.dark_theme}' : '#{theme.utterances.light_theme}' src: '!{utterancesUrl}',
ele.setAttribute('theme', nowTheme) repo: '!{repo}',
ele.setAttribute('crossorigin', 'anonymous') 'issue-term': '!{issue_term}',
ele.setAttribute('async', 'true') theme: getUtterancesTheme(document.documentElement.getAttribute('data-theme')),
document.getElementById('utterances-wrap').insertAdjacentElement('afterbegin',ele) crossorigin: 'anonymous',
async: true
},!{JSON.stringify(option)})
const ele = document.createElement('script')
for (let key in config) {
ele.setAttribute(key, config[key])
}
document.getElementById('utterances-wrap').appendChild(ele)
} }
function utterancesTheme () { const changeUtterancesTheme = theme => {
const iframe = document.querySelector('.utterances-frame') const iframe = document.querySelector('#utterances-wrap iframe')
if (iframe) { if (iframe) {
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? '#{theme.utterances.dark_theme}' : '#{theme.utterances.light_theme}'
const message = { const message = {
type: 'set-theme', type: 'set-theme',
theme: theme theme: getUtterancesTheme(theme)
}; };
iframe.contentWindow.postMessage(message, 'https://utteranc.es'); iframe.contentWindow.postMessage(message, '!{utterancesOriginUrl}')
} }
} }
if ('!{theme.comments.use[0]}' === 'Utterances' || !!{theme.comments.lazyload}) { btf.addGlobalFn('themeChange', changeUtterancesTheme, 'utterances')
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances)
if ('!{use[0]}' === 'Utterances' || !!{lazyload}) {
if (!{lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances)
else loadUtterances() else loadUtterances()
} else { } else {
function loadOtherComment () { window.loadOtherComment = loadUtterances
loadUtterances()
}
} }
})()

View File

@@ -1,33 +1,38 @@
- const { use, lazyload } = theme.comments
- const { appId, appKey, avatar, serverURLs, visitor, option } = theme.valine
- let emojiMaps = '""' - let emojiMaps = '""'
if site.data.valine if site.data.valine
- emojiMaps = JSON.stringify(site.data.valine) - emojiMaps = JSON.stringify(site.data.valine)
script. script.
function loadValine () { (() => {
function initValine () { const initValine = () => {
const valine = new Valine(Object.assign({ const valine = new Valine(Object.assign({
el: '#vcomment', el: '#vcomment',
appId: '#{theme.valine.appId}', appId: '#{appId}',
appKey: '#{theme.valine.appKey}', appKey: '#{appKey}',
avatar: '#{theme.valine.avatar}', avatar: '#{avatar}',
serverURLs: '#{theme.valine.serverURLs}', serverURLs: '#{serverURLs}',
emojiMaps: !{emojiMaps}, emojiMaps: !{emojiMaps},
path: window.location.pathname, path: window.location.pathname,
visitor: #{theme.valine.visitor} visitor: #{visitor}
}, !{JSON.stringify(theme.valine.option)})) }, !{JSON.stringify(option)}))
} }
const loadValine = async () => {
if (typeof Valine === 'function') initValine() if (typeof Valine === 'function') initValine()
else getScript('!{url_for(theme.asset.valine)}').then(initValine) else {
await btf.getScript('!{url_for(theme.asset.valine)}')
initValine()
}
} }
if ('!{theme.comments.use[0]}' === 'Valine' || !!{theme.comments.lazyload}) { if ('!{use[0]}' === 'Valine' || !!{lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('vcomment'),loadValine) if (!{lazyload}) btf.loadComment(document.getElementById('vcomment'),loadValine)
else setTimeout(loadValine, 0) else setTimeout(loadValine, 0)
} else { } else {
function loadOtherComment () { window.loadOtherComment = loadValine
loadValine()
}
} }
})()

View File

@@ -2,16 +2,11 @@
- const { lazyload, count, use } = theme.comments - const { lazyload, count, use } = theme.comments
script. script.
function loadWaline () { (() => {
function insertCSS () { let initFn = window.walineFn || null
const link = document.createElement("link")
link.rel = "stylesheet"
link.href = "!{url_for(theme.asset.waline_css)}"
document.head.appendChild(link)
}
function initWaline () { const initWaline = (Fn) => {
const waline = Waline.init(Object.assign({ const waline = Fn(Object.assign({
el: '#waline-wrap', el: '#waline-wrap',
serverURL: '!{serverURL}', serverURL: '!{serverURL}',
pageview: !{lazyload ? false : pageview}, pageview: !{lazyload ? false : pageview},
@@ -19,12 +14,24 @@ script.
path: window.location.pathname, path: window.location.pathname,
comment: !{lazyload ? false : count}, comment: !{lazyload ? false : count},
}, !{JSON.stringify(option)})) }, !{JSON.stringify(option)}))
const destroyWaline = () => {
waline.destroy()
} }
if (typeof Waline === 'function') initWaline() btf.addGlobalFn('pjaxSendOnce', destroyWaline, 'destroyWaline')
}
const loadWaline = () => {
if (initFn) initWaline(initFn)
else { else {
insertCSS() btf.getCSS('!{url_for(theme.asset.waline_css)}')
getScript('!{url_for(theme.asset.waline_js)}').then(initWaline) .then(() => import('!{url_for(theme.asset.waline_js)}'))
.then(({ init }) => {
initFn = init || Waline.init
initWaline(initFn)
window.walineFn = initFn
})
} }
} }
@@ -32,9 +39,7 @@ script.
if (!{lazyload}) btf.loadComment(document.getElementById('waline-wrap'),loadWaline) if (!{lazyload}) btf.loadComment(document.getElementById('waline-wrap'),loadWaline)
else setTimeout(loadWaline, 0) else setTimeout(loadWaline, 0)
} else { } else {
function loadOtherComment () { window.loadOtherComment = loadWaline
loadWaline()
}
} }
})()

View File

@@ -24,12 +24,12 @@ if theme.activate_power_mode.enable
if theme.click_heart && theme.click_heart.enable if theme.click_heart && theme.click_heart.enable
script#click-heart(src=url_for(theme.asset.click_heart) async mobile=`${theme.click_heart.mobile}`) script#click-heart(src=url_for(theme.asset.click_heart) async mobile=`${theme.click_heart.mobile}`)
if theme.ClickShowText && theme.ClickShowText.enable if theme.clickShowText && theme.clickShowText.enable
script#click-show-text( script#click-show-text(
src= url_for(theme.asset.ClickShowText) src= url_for(theme.asset.clickShowText)
data-mobile= `${theme.ClickShowText.mobile}` data-mobile= `${theme.clickShowText.mobile}`
data-text= theme.ClickShowText.text.join(",") data-text= theme.clickShowText.text.join(",")
data-fontsize= theme.ClickShowText.fontSize data-fontsize= theme.clickShowText.fontSize
data-random= `${theme.ClickShowText.random}` data-random= `${theme.clickShowText.random}`
async async
) )

View File

@@ -1,17 +1,10 @@
if theme.mathjax && theme.mathjax.enable case theme.math.use
if theme.mathjax.per_page when 'mathjax'
if is_post() || is_page() if (theme.math.per_page && (is_post() || is_page())) || page.mathjax
include ./mathjax.pug
else
if page.mathjax
include ./mathjax.pug include ./mathjax.pug
if theme.katex && theme.katex.enable when 'katex'
if theme.katex.per_page if (theme.math.per_page && (is_post() || is_page())) || page.katex
if is_post() || is_page()
include ./katex.pug
else
if page.katex
include ./katex.pug include ./katex.pug
if theme.mermaid.enable if theme.mermaid.enable

View File

@@ -1,10 +1,16 @@
link(rel="stylesheet" type="text/css" href=theme.asset.katex)
script(src=url_for(theme.asset.katex_copytex))
link(rel="stylesheet" type="text/css" href=theme.asset.katex_copytex_css)
script. script.
(() => { (async () => {
document.querySelectorAll('#article-container span.katex-display').forEach(item => { const showKatex = () => {
btf.wrap(item, 'div', { class: 'katex-wrap'}) document.querySelectorAll('#article-container .katex').forEach(el => el.classList.add('katex-show'))
}) }
})()
if (!window.katex_js_css) {
window.katex_js_css = true
await btf.getCSS('!{url_for(theme.asset.katex)}')
if (!{theme.math.katex.copy_tex}) {
await btf.getScript('!{url_for(theme.asset.katex_copytex)}')
}
}
showKatex()
})()

View File

@@ -1,15 +1,19 @@
//- Mathjax 3 //- Mathjax 3
- const { tags, enableMenu } = theme.math.mathjax
script. script.
(() => {
const loadMathjax = () => {
if (!window.MathJax) { if (!window.MathJax) {
window.MathJax = { window.MathJax = {
tex: { tex: {
inlineMath: [ ['$','$'], ["\\(","\\)"]], inlineMath: [['$', '$'], ['\\(', '\\)']],
tags: 'ams' tags: '!{tags}',
}, },
chtml: { chtml: {
scale: 1.2 scale: 1.1
}, },
options: { options: {
enableMenu: !{enableMenu},
renderActions: { renderActions: {
findScript: [10, doc => { findScript: [10, doc => {
for (const node of document.querySelectorAll('script[type^="math/tex"]')) { for (const node of document.querySelectorAll('script[type^="math/tex"]')) {
@@ -21,28 +25,23 @@ script.
math.end = {node: text, delim: '', n: 0} math.end = {node: text, delim: '', n: 0}
doc.math.push(math) doc.math.push(math)
} }
}, ''], }, '']
insertScript: [200, () => {
document.querySelectorAll('mjx-container:not\([display]\)').forEach(node => {
const target = node.parentNode
if (target.nodeName.toLowerCase() === 'li') {
target.parentNode.classList.add('has-jax')
} else {
target.classList.add('has-jax')
}
});
}, '', false]
} }
} }
} }
const script = document.createElement('script') const script = document.createElement('script')
script.src = '!{theme.asset.mathjax}' script.src = '!{url_for(theme.asset.mathjax)}'
script.id = 'MathJax-script' script.id = 'MathJax-script'
script.async = true script.async = true
document.head.appendChild(script) document.head.appendChild(script)
} else { } else {
MathJax.startup.document.state(0) MathJax.startup.document.state(0)
MathJax.texReset() MathJax.texReset()
MathJax.typeset() MathJax.typesetPromise()
} }
}
btf.addGlobalFn('encrypt', loadMathjax, 'mathjax')
window.pjax ? loadMathjax() : window.addEventListener('load', loadMathjax)
})()

View File

@@ -1,26 +1,51 @@
script. script.
(() => { (() => {
const $mermaidWrap = document.querySelectorAll('#article-container .mermaid-wrap') const runMermaid = ele => {
if ($mermaidWrap.length) {
window.runMermaid = () => {
window.loadMermaid = true window.loadMermaid = true
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? '!{theme.mermaid.theme.dark}' : '!{theme.mermaid.theme.light}' const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? '!{theme.mermaid.theme.dark}' : '!{theme.mermaid.theme.light}'
Array.from($mermaidWrap).forEach((item, index) => { ele.forEach((item, index) => {
const mermaidSrc = item.firstElementChild const mermaidSrc = item.firstElementChild
const mermaidThemeConfig = '%%{init:{ \'theme\':\'' + theme + '\'}}%%\n' const mermaidThemeConfig = `%%{init:{ 'theme':'${theme}'}}%%\n`
const mermaidID = 'mermaid-' + index const mermaidID = `mermaid-${index}`
const mermaidDefinition = mermaidThemeConfig + mermaidSrc.textContent const mermaidDefinition = mermaidThemeConfig + mermaidSrc.textContent
mermaid.mermaidAPI.render(mermaidID, mermaidDefinition, (svgCode) => {
mermaidSrc.insertAdjacentHTML('afterend', svgCode) const renderFn = mermaid.render(mermaidID, mermaidDefinition)
const renderMermaid = svg => {
mermaidSrc.insertAdjacentHTML('afterend', svg)
}
// mermaid v9 and v10 compatibility
typeof renderFn === 'string' ? renderMermaid(renderFn) : renderFn.then(({ svg }) => renderMermaid(svg))
}) })
}
const codeToMermaid = () => {
const codeMermaidEle = document.querySelectorAll('pre > code.mermaid')
if (codeMermaidEle.length === 0) return
codeMermaidEle.forEach(ele => {
const preEle = document.createElement('pre')
preEle.className = 'mermaid-src'
preEle.hidden = true
preEle.textContent = ele.textContent
const newEle = document.createElement('div')
newEle.className = 'mermaid-wrap'
newEle.appendChild(preEle)
ele.parentNode.replaceWith(newEle)
}) })
} }
const loadMermaid = () => { const loadMermaid = () => {
window.loadMermaid ? runMermaid() : getScript('!{theme.asset.mermaid}').then(runMermaid) if (!{theme.mermaid.code_write}) codeToMermaid()
const $mermaid = document.querySelectorAll('#article-container .mermaid-wrap')
if ($mermaid.length === 0) return
const runMermaidFn = () => runMermaid($mermaid)
btf.addGlobalFn('themeChange', runMermaidFn, 'mermaid')
window.loadMermaid ? runMermaidFn() : btf.getScript('!{url_for(theme.asset.mermaid)}').then(runMermaidFn)
} }
btf.addGlobalFn('encrypt', loadMermaid, 'mermaid')
window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid) window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
}
})() })()

View File

@@ -0,0 +1,64 @@
- const { server, site, option } = theme.artalk
- const avatarCdn = (option !== null && option.gravatar && option.gravatar.mirror) || ''
- const avatarDefault = (option !== null && option.gravatar && (option.gravatar.params || option.gravatar.default)) || ''
!= partial("includes/third-party/newest-comments/common.pug", {}, { cache: true })
script.
window.addEventListener('load', () => {
const keyName = 'artalk-newest-comments'
const { changeContent, generateHtml, run } = window.newestComments
const getAvatarValue = async () => {
const predefinedAvatarCdn = '!{avatarCdn}'
const predefinedAvatarDefault = '!{avatarDefault}'
const avatarDefaultFormat = e => e.startsWith('d=') ? e : `d=${e}`
if (predefinedAvatarCdn && predefinedAvatarDefault) {
return { avatarCdn: predefinedAvatarCdn, avatarDefault: avatarDefaultFormat(predefinedAvatarDefault) }
}
try {
const res = await fetch('!{server}/api/v2/conf')
const result = await res.json()
const { mirror, params, default: defaults } = result.frontend_conf.gravatar
const avatarCdn = predefinedAvatarCdn || mirror
let avatarDefault = avatarDefaultFormat(predefinedAvatarDefault || params || defaults)
return { avatarCdn, avatarDefault}
} catch (e) {
console.error(e)
return { avatarCdn: predefinedAvatarCdn, avatarDefault: avatarDefaultFormat(predefinedAvatarDefault) }
}
}
const searchParams = new URLSearchParams({
'site_name': '!{site}',
'limit': '!{theme.aside.card_newest_comments.limit}',
})
const getComment = async (ele) => {
try {
const res = await fetch(`!{server}/api/v2/stats/latest_comments?${searchParams}`)
const result = await res.json()
const { avatarCdn, avatarDefault } = await getAvatarValue()
const artalk = result.data.map(e => {
const avatar = avatarCdn && e.email_encrypted ? `${avatarCdn}${e.email_encrypted}?${avatarDefault}` : ''
return {
'avatar': avatar,
'content': changeContent(e.content_marked),
'nick': e.nick,
'url': e.page_url,
'date': e.date,
}
})
btf.saveToLocal.set(keyName, JSON.stringify(artalk), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(artalk, ele)
} catch (e) {
console.log(e)
ele.textContent= "!{_p('aside.card_newest_comments.error')}"
}
}
run(keyName, getComment)
})

View File

@@ -0,0 +1,60 @@
script.
window.newestComments = {
changeContent: content => {
if (content === '') return content
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
content = content.replace(/<code>.*?<\/code>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
content = content.replace(/<[^>]+>/g, "") // remove html tag
if (content.length > 150) {
content = content.substring(0, 150) + '...'
}
return content
},
generateHtml: (array, ele) => {
let result = ''
if (array.length) {
for (let i = 0; i < array.length; i++) {
result += '<div class="aside-list-item">'
if (!{theme.aside.card_newest_comments.avatar} && array[i].avatar) {
const imgAttr = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href="${array[i].url}" class="thumbnail"><img ${imgAttr}="${array[i].avatar}" alt="${array[i].nick}"></a>`
}
result += `<div class="content">
<a class="comment" href="${array[i].url}" title="${array[i].content}">${array[i].content}</a>
<div class="name"><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
</div></div>`
}
} else {
result += '!{_p("aside.card_newest_comments.zero")}'
}
ele.innerHTML = result
window.lazyLoadInstance && window.lazyLoadInstance.update()
window.pjax && window.pjax.refresh(ele)
},
newestCommentInit: (name, getComment) => {
const $dom = document.querySelector('#card-newest-comments .aside-list')
if ($dom) {
const data = btf.saveToLocal.get(name)
if (data) {
newestComments.generateHtml(JSON.parse(data), $dom)
} else {
getComment($dom)
}
}
},
run: (name, getComment) => {
newestComments.newestCommentInit(name, getComment)
btf.addGlobalFn('pjaxComplete', () => newestComments.newestCommentInit(name, getComment), name)
}
}

View File

@@ -1,21 +1,12 @@
!= partial("includes/third-party/newest-comments/common.pug", {}, { cache: true })
script. script.
window.addEventListener('load', () => { window.addEventListener('load', () => {
const changeContent = (content) => { const keyName = 'disqus-newest-comments'
if (content === '') return content const { changeContent, generateHtml, run } = window.newestComments
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link const getComment = ele => {
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url fetch('https://disqus.com/api/3.0/forums/listPosts.json?forum=!{forum}&related=thread&limit=!{theme.aside.card_newest_comments.limit}&api_key=!{apiKey}')
content = content.replace(/<code>.*?<\/code>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
content = content.replace(/<[^>]+>/g,"") // remove html tag
if (content.length > 150) {
content = content.substring(0,150) + '...'
}
return content
}
const getComment = () => {
fetch('https://disqus.com/api/3.0/forums/listPosts.json?forum=!{forum}&related=thread&limit=!{theme.newest_comments.limit}&api_key=!{apiKey}')
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
const disqusArray = data.response.map(item => { const disqusArray = data.response.map(item => {
@@ -28,54 +19,15 @@ script.
} }
}) })
saveToLocal.set('disqus-newest-comments', JSON.stringify(disqusArray), !{theme.newest_comments.storage}/(60*24)) btf.saveToLocal.set(keyName, JSON.stringify(disqusArray), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(disqusArray) generateHtml(disqusArray, ele)
}).catch(e => { }).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list') console.error(e)
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" ele.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }
const generateHtml = array => { run(keyName, getComment)
let result = ''
if (array.length) {
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
result += `<div class='content'>
<a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
<div class='name'><span>${array[i].nick}</span><time> / ${btf.diffDate(array[i].date, true)}</time></div>
</div></div>`
}
} else {
result += '!{_p("aside.card_newest_comments.zero")}'
}
let $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= result
window.lazyLoadInstance && window.lazyLoadInstance.update()
window.pjax && window.pjax.refresh($dom)
}
const newestCommentInit = () => {
if (document.querySelector('#card-newest-comments .aside-list')) {
const data = saveToLocal.get('disqus-newest-comments')
if (data) {
generateHtml(JSON.parse(data))
} else {
getComment()
}
}
}
newestCommentInit()
document.addEventListener('pjax:complete', newestCommentInit)
}) })

View File

@@ -1,23 +1,17 @@
!= partial("includes/third-party/newest-comments/common.pug", {}, { cache: true })
script. script.
window.addEventListener('load', () => { window.addEventListener('load', () => {
const changeContent = (content) => { const keyName = 'github-newest-comments'
if (content === '') return content const { changeContent, generateHtml, run } = window.newestComments
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link const findTrueUrl = (array, ele) => {
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
content = content.replace(/<[^>]+>/g,"") // remove html tag
if (content.length > 150) {
content = content.substring(0,150) + '...'
}
return content
}
const findTrueUrl = (array) => {
Promise.all(array.map(item => Promise.all(array.map(item =>
fetch(item.url).then(resp => resp.json()).then(data => { fetch(item.url).then(resp => resp.json()).then(data => {
const urlArray = data.body.match(/(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/ig) let urlArray = data.body ? data.body.match(/(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/ig) : []
if (!Array.isArray(urlArray) || urlArray.length === 0) {
urlArray = [`${data.html_url}`]
}
if (data.user.login === 'utterances-bot') { if (data.user.login === 'utterances-bot') {
return urlArray.pop() return urlArray.pop()
} else { } else {
@@ -32,13 +26,13 @@ script.
} }
}) })
saveToLocal.set('github-newest-comments', JSON.stringify(array), !{theme.newest_comments.storage}/(60*24)) btf.saveToLocal.set(keyName, JSON.stringify(array), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(array) generateHtml(array, ele)
}); });
} }
const getComment = () => { const getComment = ele => {
fetch('https://api.github.com/repos/!{userRepo}/issues/comments?sort=updated&direction=desc&per_page=!{theme.newest_comments.limit}&page=1',{ fetch('https://api.github.com/repos/!{userRepo}/issues/comments?sort=updated&direction=desc&per_page=!{theme.aside.card_newest_comments.limit}&page=1',{
"headers": { "headers": {
Accept: 'application/vnd.github.v3.html+json' Accept: 'application/vnd.github.v3.html+json'
} }
@@ -48,60 +42,19 @@ script.
const githubArray = data.map(item => { const githubArray = data.map(item => {
return { return {
'avatar': item.user.avatar_url, 'avatar': item.user.avatar_url,
'content': changeContent(item.body_html), 'content': changeContent(item.body_html || item.body),
'nick': item.user.login, 'nick': item.user.login,
'url': item.issue_url, 'url': item.issue_url,
'date': item.updated_at, 'date': item.updated_at
'githubUrl': item.html_url
} }
}) })
findTrueUrl(githubArray) findTrueUrl(githubArray, ele)
}).catch(e => { }).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list') console.error(e)
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" ele.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }
run(keyName, getComment)
const generateHtml = array => {
let result = ''
if (array.length) {
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
result += `<div class='content'>
<a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
<div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
</div></div>`
}
} else {
result += '!{_p("aside.card_newest_comments.zero")}'
}
let $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= result
window.lazyLoadInstance && window.lazyLoadInstance.update()
window.pjax && window.pjax.refresh($dom)
}
const newestCommentInit = () => {
if (document.querySelector('#card-newest-comments .aside-list')) {
const data = saveToLocal.get('github-newest-comments')
if (data) {
generateHtml(JSON.parse(data))
} else {
getComment()
}
}
}
newestCommentInit()
document.addEventListener('pjax:complete', newestCommentInit)
}) })

View File

@@ -24,3 +24,7 @@ if use
when 'Utterances' when 'Utterances'
- userRepo = theme.utterances.repo - userRepo = theme.utterances.repo
include ./github-issues.pug include ./github-issues.pug
when 'Remark42'
include ./remark42.pug
when 'Artalk'
include ./artalk.pug

View File

@@ -0,0 +1,30 @@
- const { host, siteId } = theme.remark42
script.
window.addEventListener('load', () => {
const keyName = 'remark42-newest-comments'
const { changeContent, generateHtml, run } = window.newestComments
const getComment = ele => {
fetch('!{host}/api/v1/last/!{theme.aside.card_newest_comments.limit}?site=!{siteId}')
.then(response => response.json())
.then(data => {
const remark42 = data.map(e => {
return {
'avatar': e.user.picture,
'content': changeContent(e.text),
'nick': e.user.name,
'url': e.locator.url,
'date': e.time,
}
})
btf.saveToLocal.set(keyName, JSON.stringify(remark42), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(remark42, ele)
}).catch(e => {
console.error(e)
ele.textContent= "!{_p('aside.card_newest_comments.error')}"
})
}
run(keyName, getComment)
})

View File

@@ -1,27 +1,18 @@
!= partial("includes/third-party/newest-comments/common.pug", {}, { cache: true })
script. script.
window.addEventListener('load', () => { window.addEventListener('load', () => {
const changeContent = (content) => { const keyName = 'twikoo-newest-comments'
if (content === '') return content const { changeContent, generateHtml, run } = window.newestComments
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link const getComment = ele => {
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
content = content.replace(/<[^>]+>/g,"") // remove html tag
if (content.length > 150) {
content = content.substring(0,150) + '...'
}
return content
}
const getComment = () => {
const runTwikoo = () => { const runTwikoo = () => {
twikoo.getRecentComments({ twikoo.getRecentComments({
envId: '!{theme.twikoo.envId}', envId: '!{theme.twikoo.envId}',
region: '!{theme.twikoo.region}', region: '!{theme.twikoo.region}',
pageSize: !{theme.newest_comments.limit}, pageSize: !{theme.aside.card_newest_comments.limit},
includeReply: true includeReply: true
}).then(function (res) { }).then(res => {
const twikooArray = res.map(e => { const twikooArray = res.map(e => {
return { return {
'content': changeContent(e.comment), 'content': changeContent(e.comment),
@@ -32,61 +23,22 @@ script.
} }
}) })
saveToLocal.set('twikoo-newest-comments', JSON.stringify(twikooArray), !{theme.newest_comments.storage}/(60*24)) btf.saveToLocal.set(keyName, JSON.stringify(twikooArray), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(twikooArray) generateHtml(twikooArray, ele)
}).catch(function (err) { }).catch(err => {
const $dom = document.querySelector('#card-newest-comments .aside-list') console.error(err)
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" ele.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }
if (typeof twikoo === 'object') { if (typeof twikoo === 'object') {
runTwikoo() runTwikoo()
} else { } else {
getScript('!{theme.asset.twikoo}').then(runTwikoo) btf.getScript('!{url_for(theme.asset.twikoo)}').then(runTwikoo)
} }
} }
const generateHtml = array => { run(keyName, getComment)
let result = ''
if (array.length) {
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
result += `<div class='content'>
<a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
<div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
</div></div>`
}
} else {
result += '!{_p("aside.card_newest_comments.zero")}'
}
let $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= result
window.lazyLoadInstance && window.lazyLoadInstance.update()
window.pjax && window.pjax.refresh($dom)
}
const newestCommentInit = () => {
if (document.querySelector('#card-newest-comments .aside-list')) {
const data = saveToLocal.get('twikoo-newest-comments')
if (data) {
generateHtml(JSON.parse(data))
} else {
getComment()
}
}
}
newestCommentInit()
document.addEventListener('pjax:complete', newestCommentInit)
}) })

View File

@@ -1,21 +1,12 @@
- let default_avatar = theme.valine.avatar - let default_avatar = theme.valine.avatar
script(src=url_for(theme.asset.blueimp_md5)) script(src=url_for(theme.asset.blueimp_md5))
!= partial("includes/third-party/newest-comments/common.pug", {}, { cache: true })
script. script.
window.addEventListener('load', () => { window.addEventListener('load', () => {
const changeContent = (content) => { const keyName = 'valine-newest-comments'
if (content === '') return content const { changeContent, generateHtml, run } = window.newestComments
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code
content = content.replace(/<[^>]+>/g,"") // remove html tag
if (content.length > 150) {
content = content.substring(0,150) + '...'
}
return content
}
const getIcon = (icon, mail) => { const getIcon = (icon, mail) => {
if (icon) return icon if (icon) return icon
@@ -24,34 +15,7 @@ script.
return iconUrl return iconUrl
} }
const generateHtml = array => { const getComment = ele => {
let result = ''
if (array.length) {
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
result += `<div class='content'>
<a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
<div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
</div></div>`
}
} else {
result += '!{_p("aside.card_newest_comments.zero")}'
}
let $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= result
window.lazyLoadInstance && window.lazyLoadInstance.update()
window.pjax && window.pjax.refresh($dom)
}
const getComment = () => {
const serverURL = '!{theme.valine.serverURLs || `https://${theme.valine.appId.substring(0,8)}.api.lncldglobal.com` }' const serverURL = '!{theme.valine.serverURLs || `https://${theme.valine.appId.substring(0,8)}.api.lncldglobal.com` }'
var settings = { var settings = {
@@ -63,10 +27,10 @@ script.
}, },
} }
fetch(`${serverURL}/1.1/classes/Comment?limit=!{theme.newest_comments.limit}&order=-createdAt`,settings) fetch(`${serverURL}/1.1/classes/Comment?limit=!{theme.aside.card_newest_comments.limit}&order=-createdAt`,settings)
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
const valineArray = data.results.map(function (e) { const valineArray = data.results.map(e => {
return { return {
'avatar': getIcon(e.QQAvatar, e.mail), 'avatar': getIcon(e.QQAvatar, e.mail),
'content': changeContent(e.comment), 'content': changeContent(e.comment),
@@ -75,25 +39,13 @@ script.
'date': e.updatedAt, 'date': e.updatedAt,
} }
}) })
saveToLocal.set('valine-newest-comments', JSON.stringify(valineArray), !{theme.newest_comments.storage}/(60*24)) btf.saveToLocal.set(keyName, JSON.stringify(valineArray), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(valineArray) generateHtml(valineArray, ele)
}).catch(e => { }).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list') console.error(e)
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" ele.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }
const newestCommentInit = () => { run(keyName, getComment)
if (document.querySelector('#card-newest-comments .aside-list')) {
const data = saveToLocal.get('valine-newest-comments')
if (data) {
generateHtml(JSON.parse(data))
} else {
getComment()
}
}
}
newestCommentInit()
document.addEventListener('pjax:complete', newestCommentInit)
}) })

View File

@@ -1,84 +1,32 @@
- const serverURL = theme.waline.serverURL.replace(/\/$/, '')
!= partial("includes/third-party/newest-comments/common.pug", {}, { cache: true })
script. script.
window.addEventListener('load', () => { window.addEventListener('load', () => {
const changeContent = (content) => { const keyName = 'waline-newest-comments'
if (content === '') return content const { changeContent, generateHtml, run } = window.newestComments
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[!{_p("aside.card_newest_comments.image")}]') // replace image link const getComment = async (ele) => {
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[!{_p("aside.card_newest_comments.link")}]') // replace url try {
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[!{_p("aside.card_newest_comments.code")}]') // replace code const res = await fetch('!{serverURL}/api/comment?type=recent&count=!{theme.aside.card_newest_comments.limit}', { method: 'GET' })
content = content.replace(/<[^>]+>/g,"") // remove html tag const result = await res.json()
const walineArray = result.data.map(e => {
if (content.length > 150) {
content = content.substring(0,150) + '...'
}
return content
}
const generateHtml = array => {
let result = ''
if (array.length) {
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (!{theme.newest_comments.avatar}) {
const name = '!{theme.lazyload.enable ? "data-lazy-src" : "src"}'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
result += `<div class='content'>
<a class='comment' href='${array[i].url}' title='${array[i].content}'>${array[i].content}</a>
<div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
</div></div>`
}
} else {
result += '!{_p("aside.card_newest_comments.zero")}'
}
let $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= result
window.lazyLoadInstance && window.lazyLoadInstance.update()
window.pjax && window.pjax.refresh($dom)
}
const getComment = () => {
const loadWaline = () => {
Waline.RecentComments({
serverURL: '!{theme.waline.serverURL}',
count: !{theme.newest_comments.limit}
}).then(({comments}) => {
const walineArray = comments.map(e => {
return { return {
'content': changeContent(e.comment), 'content': changeContent(e.comment),
'avatar': e.avatar, 'avatar': e.avatar,
'nick': e.nick, 'nick': e.nick,
'url': e.url + '#' + e.objectId, 'url': e.url + '#' + e.objectId,
'date': e.insertedAt, 'date': e.time || e.insertedAt
} }
}) })
saveToLocal.set('waline-newest-comments', JSON.stringify(walineArray), !{theme.newest_comments.storage}/(60*24)) btf.saveToLocal.set(keyName, JSON.stringify(walineArray), !{theme.aside.card_newest_comments.storage}/(60*24))
generateHtml(walineArray) generateHtml(walineArray, ele)
}).catch(e => { } catch (err) {
const $dom = document.querySelector('#card-newest-comments .aside-list') console.error(err)
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" ele.textContent= "!{_p('aside.card_newest_comments.error')}"
})
}
if (typeof Waline === 'function') loadWaline()
else getScript('!{url_for(theme.asset.waline_js)}').then(loadWaline)
}
const newestCommentInit = () => {
if (document.querySelector('#card-newest-comments .aside-list')) {
const data = saveToLocal.get('waline-newest-comments')
if (data) {
generateHtml(JSON.parse(data))
} else {
getComment()
}
} }
} }
newestCommentInit() run(keyName, getComment)
document.addEventListener('pjax:complete', newestCommentInit)
}) })

View File

@@ -1,15 +1,16 @@
script. script.
function panguFn () { (() => {
const panguFn = () => {
if (typeof pangu === 'object') pangu.autoSpacingPage() if (typeof pangu === 'object') pangu.autoSpacingPage()
else { else {
getScript('!{url_for(theme.asset.pangu)}') btf.getScript('!{url_for(theme.asset.pangu)}')
.then(() => { .then(() => {
pangu.autoSpacingPage() pangu.autoSpacingPage()
}) })
} }
} }
function panguInit () { const panguInit = () => {
if (!{theme.pangu.field === 'post'}){ if (!{theme.pangu.field === 'post'}){
GLOBAL_CONFIG_SITE.isPost && panguFn() GLOBAL_CONFIG_SITE.isPost && panguFn()
} else { } else {
@@ -17,4 +18,6 @@ script.
} }
} }
btf.addGlobalFn('pjaxComplete', panguInit, 'pangu')
document.addEventListener('DOMContentLoaded', panguInit) document.addEventListener('DOMContentLoaded', panguInit)
})()

View File

@@ -1,22 +1,23 @@
- var pjaxExclude = 'a:not([target="_blank"])' - var pjaxExclude = 'a:not([target="_blank"])'
if theme.pjax.exclude if theme.pjax.exclude
each val in theme.pjax.exclude each val in theme.pjax.exclude
- pjaxExclude = pjaxExclude + `:not([href="${val}"])` - pjaxExclude += `:not([href="${val}"])`
- let pjaxSelectors = ['title','#config-diff','#body-wrap','#rightside-config-hide','#rightside-config-show','.js-pjax'] - let pjaxSelectors = ['head > title', '#config-diff', '#body-wrap', '#rightside-config-hide', '#rightside-config-show', '.js-pjax']
- let choose = theme.comments.use - let choose = theme.comments.use
if choose if choose
if theme.Open_Graph_meta && (choose.includes('Livere') || choose.includes('Utterances') || choose.includes('Giscus')) if theme.Open_Graph_meta.enable && (choose.includes('Livere') || choose.includes('Utterances') || choose.includes('Giscus'))
- pjaxSelectors.unshift('meta[property="og:image"]', 'meta[property="og:title"]', 'meta[property="og:url"]') - pjaxSelectors.unshift('meta[property="og:image"]', 'meta[property="og:title"]', 'meta[property="og:url"]')
if choose.includes('Utterances') || choose.includes('Giscus') if choose.includes('Utterances') || choose.includes('Giscus')
- pjaxSelectors.unshift('link[rel="canonical"]') - pjaxSelectors.unshift('link[rel="canonical"]')
script(src=url_for(theme.asset.pjax)) script(src=url_for(theme.asset.pjax))
script. script.
let pjaxSelectors = !{JSON.stringify(pjaxSelectors)} (() => {
const pjaxSelectors = !{JSON.stringify(pjaxSelectors)}
var pjax = new Pjax({ window.pjax = new Pjax({
elements: '!{pjaxExclude}', elements: '!{pjaxExclude}',
selectors: pjaxSelectors, selectors: pjaxSelectors,
cacheBust: false, cacheBust: false,
@@ -24,34 +25,25 @@ script.
scrollRestoration: false scrollRestoration: false
}) })
document.addEventListener('pjax:send', function () { const triggerPjaxFn = (val) => {
if (!val) return
// removeEventListener scroll Object.values(val).forEach(fn => fn())
window.tocScrollFn && window.removeEventListener('scroll', window.tocScrollFn)
window.scrollCollect && window.removeEventListener('scroll', scrollCollect)
typeof preloader === 'object' && preloader.initLoading()
document.getElementById('rightside').style.cssText = "opacity: ''; transform: ''"
if (window.aplayers) {
for (let i = 0; i < window.aplayers.length; i++) {
if (!window.aplayers[i].options.fixed) {
window.aplayers[i].destroy()
}
}
} }
typeof typed === 'object' && typed.destroy() document.addEventListener('pjax:send', () => {
// removeEventListener
btf.removeGlobalFnEvent('pjaxSendOnce')
btf.removeGlobalFnEvent('themeChange')
// reset readmode // reset readmode
const $bodyClassList = document.body.classList const $bodyClassList = document.body.classList
$bodyClassList.contains('read-mode') && $bodyClassList.remove('read-mode') if ($bodyClassList.contains('read-mode')) $bodyClassList.remove('read-mode')
triggerPjaxFn(window.globalFn.pjaxSend)
}) })
document.addEventListener('pjax:complete', function () { document.addEventListener('pjax:complete', () => {
window.refreshFn() btf.removeGlobalFnEvent('pjaxCompleteOnce')
document.querySelectorAll('script[data-pjax]').forEach(item => { document.querySelectorAll('script[data-pjax]').forEach(item => {
const newScript = document.createElement('script') const newScript = document.createElement('script')
const content = item.text || item.textContent || item.innerHTML || "" const content = item.text || item.textContent || item.innerHTML || ""
@@ -60,27 +52,12 @@ script.
item.parentNode.replaceChild(newScript, item) item.parentNode.replaceChild(newScript, item)
}) })
GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update() triggerPjaxFn(window.globalFn.pjaxComplete)
typeof chatBtnFn === 'function' && chatBtnFn()
typeof panguInit === 'function' && panguInit()
// google analytics
typeof gtag === 'function' && gtag('config', '!{theme.google_analytics}', {'page_path': window.location.pathname});
// baidu analytics
typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]);
typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()
// prismjs
typeof Prism === 'object' && Prism.highlightAll()
typeof preloader === 'object' && preloader.endLoading()
}) })
document.addEventListener('pjax:error', (e) => { document.addEventListener('pjax:error', e => {
if (e.request.status === 404) { if (e.request.status === 404) {
pjax.loadUrl('/404.html') pjax.loadUrl('!{url_for("/404.html")}')
} }
}) })
})()

View File

@@ -1,5 +1,23 @@
if config.prismjs && config.prismjs.enable && !config.prismjs.preprocess - const { prismjs_js, prismjs_autoloader, prismjs_lineNumber_js } = theme.asset
script(src=url_for(theme.asset.prismjs_js)) - const { prismjs, syntax_highlighter } = config
script(src=url_for(theme.asset.prismjs_autoloader)) - const { enable, preprocess, line_number } = prismjs
if config.prismjs.line_number
script(src=url_for(theme.asset.prismjs_lineNumber_js)) if (syntax_highlighter === 'prismjs' || enable) && !preprocess
script.
(() => {
window.Prism = window.Prism || {}
window.Prism.manual = true
const highlightAll = () => {
window.Prism.highlightAll()
}
window.addEventListener('load', highlightAll)
btf.addGlobalFn('pjaxComplete', highlightAll, 'prismjs')
btf.addGlobalFn('encrypt', highlightAll, 'prismjs')
})()
script(src=url_for(prismjs_js))
script(src=url_for(prismjs_autoloader))
if (line_number)
script(src=url_for(prismjs_lineNumber_js))

View File

@@ -16,3 +16,7 @@
.algolia-poweredBy .algolia-poweredBy
#search-mask #search-mask
script(src=url_for(theme.asset.algolia_search))
script(src=url_for(theme.asset.instantsearch))
script(src=url_for(theme.asset.algolia_js))

Some files were not shown because too many files have changed in this diff Show More