提交 20bcf0c5 编写于 作者: P Pengcc

selfhexo

上级 8d4d9efe
node_modules .DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
.history/
themes/_landscape/
themes/_next/
themes/_vexo/
themes/_casper/
HWTianDaoCHouQin.*
FZZhongKaiFan.*
HuaWeiHaiSiYingHeTi.*
\ No newline at end of file
# Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/
# Site
# title: 彭长超的博客
title: Hexo
subtitle: ''
description: ''
keywords: 后端, 前端
author: Pengcc
language: zh-CN
# language: en
timezone: Asia/Shanghai
# URL
## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project'
# url: https://13812700839.github.io
url: http://10.10.216.58:4000
root: /
permalink: :category/:year/:month/:day/:title-:hash/
permalink_defaults:
lang: en
pretty_urls:
trailing_index: true # Set to false to remove trailing 'index.html' from permalinks
trailing_html: true # Set to false to remove trailing '.html' from permalinks
# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:
# Writing
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link:
enable: true # Open external links in new tab
field: site # Apply to the whole site
exclude: ''
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
highlight:
enable: true
line_number: true
auto_detect: false
tab_replace: ''
wrap: true
hljs: false
prismjs:
enable: false
preprocess: true
line_number: true
tab_replace: ''
# Home page setting
# path: Root path for your blogs index page. (default = '')
# per_page: Posts displayed per page. (0 = disable pagination)
# order_by: Posts order. (Order by date descending by default)
index_generator:
path: ''
per_page: 10
order_by: -date
# Category & Tag
default_category: uncategorized
category_map:
前端: frontEnd
后端: bakEnd
版本控制: versionControl
Windows软件安装配置: windowsSoftware
数据库: database
中间件: middleware
其他: other
tag_map:
Java: java
Python: python
Vue: vue
# Metadata elements
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
meta_generator: true
# Date / Time format
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss
## updated_option supports 'mtime', 'date', 'empty'
updated_option: 'mtime'
# Pagination
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page
# Include / Exclude file(s)
## include:/exclude: options only apply to the 'source/' folder
include:
exclude:
ignore:
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: volantis
# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
type: 'git'
repo: root@47.100.225.227:/opt/hexo-blog/hexo.git
branch: master
# - type: git
# repo:
# github: git@github.com:13812700839/selfhexo.git
# gitee: git@gitee.com:pengchangchao/hexo.git
# coding: git@e.coding.net:huashanghun/selfproject/hexo.git
# # gitcafe: https://gitcafe.com/pengloo53/pengloo53.git
# branch: main
# type: heroku
# repo: https://git.heroku.com/pengcc.git
# branch: main
{ {
"name": "cloud-ide-1024-game", "name": "hexo-site",
"version": "1.0.0", "version": "0.0.0",
"description": "", "private": true,
"main": "index.js",
"scripts": { "scripts": {
"dev": "live-server" "build": "hexo generate",
"clean": "hexo clean",
"deploy": "hexo deploy",
"server": "hexo server",
"start": "hexo server -p $PORT",
"dev": "hexo server -p $PORT",
"push": "hexo clean && hexo generate && hexo deploy"
},
"hexo": {
"version": "5.4.0"
}, },
"author": "Aresn",
"license": "MIT",
"dependencies": { "dependencies": {
"live-server": "^1.2.2" "hexo": "^5.0.0",
"hexo-deployer-git": "^3.0.0",
"hexo-generator-archive": "^1.0.0",
"hexo-generator-category": "^1.0.0",
"hexo-generator-index": "^2.0.0",
"hexo-generator-json-content": "^4.2.3",
"hexo-generator-tag": "^1.0.0",
"hexo-related-popular-posts": "5.0.1",
"hexo-renderer-ejs": "^1.0.0",
"hexo-renderer-marked": "^4.0.0",
"hexo-renderer-stylus": "^2.0.0",
"hexo-server": "^2.0.0",
"hexo-wordcount": "^6.0.1"
} }
} }
# preview.yml # preview.yml
autoOpen: true # 打开工作空间时是否自动开启所有应用的预览 autoOpen: false # 打开工作空间时是否自动开启所有应用的预览
apps: apps:
- port: 3000 # 应用的端口 - port: 5500 # 应用的端口
run: npm i && npm run dev # 应用的启动命令 run: yarn install && yarn server # 应用的启动命
command: # 使用此命令启动服务,且不执行run command: # 使用此命令启动服务,且不执行run
root: ./ # 应用的启动目录 root: ./ # 应用的启动目录
name: 1024云IDE挑战赛项目 # 应用名称 name: selfhexo # 应用名称
description: 1024云IDE挑战赛项目。 # 应用描述 description: 我的第一个 Blog。 # 应用描述
autoOpen: true # 打开工作空间时是否自动开启预览(优先级高于根级 autoOpen autoOpen: true # 打开工作空间时是否自动开启预览(优先级高于根级 autoOpen
\ No newline at end of file
---
id:
title: {{ title }}
date: {{ date }}
updated: {{ date }}
author: Pengcc
tags:
- untagged
categories:
- uncategorized
keywords: keyword, keyword1
description: description
---
---
id:
title: {{ title }}
date: {{ date }}
updated: {{ date }}
author: Pengcc
tags:
- untagged
categories:
- uncategorized
keywords: keyword, keyword1
description: description
---
\ No newline at end of file
---
id:
title: {{ title }}
date: {{ date }}
updated: {{ date }}
author: Pengcc
tags:
- untagged
categories:
- uncategorized
keywords: keyword, keyword1
description: description
---
---
title: How to use Hexo
tags:
- default
categories:
- 其他
---
Welcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues).
## Quick Start
### Create a new post
``` bash
$ hexo new "My New Post"
```
More info: [Writing](https://hexo.io/docs/writing.html)
### Run server
``` bash
$ hexo server
```
More info: [Server](https://hexo.io/docs/server.html)
### Generate static files
``` bash
$ hexo generate
```
More info: [Generating](https://hexo.io/docs/generating.html)
### Deploy to remote sites
``` bash
$ hexo deploy
```
More info: [Deployment](https://hexo.io/docs/one-command-deployment.html)
---
title: note
author: Pengcc
date: 2021-12-23 16:22:05
updated: 2021-12-23 16:22:05
tags:
categories:
---
git hooks
Springboot @Configure
Springboot @Value
Springboot @ConfigurationProteries
docker部署
docker-compose部署
---
id: 1
title: Linux 的 Git 学习笔记(一)
description: Linux 的 Git 学习笔记(一)
date: 2021-12-20 16:57:36
updated: 2021-12-20 16:57:36
author: Pengcc
tags:
- 版本控制
- git
categories:
- 版本控制
- git
keywords: git, Git, linux, Linux, 版本控制
---
## 克隆git仓库
```bash
git clone <git仓库的URL>
```
## 创建并初始化git仓库(在仓库内执行)
```bash
git init
```
## 查看当前git仓库的状态
```bash
git status
```
## 用git add命令将新建文件加入缓存区
```bash
git add <文件名>
```
## 查看缓存区哪些文件被修改
```bash
git diff --cached
```
## 提交文件到本地仓库
```bash
git commit -m "提交文件注释"
```
## 连接git远程仓库
```bash
git remote add origin <git仓库的URL>
```
## 创建git新分支
```bash
git branch <分支名>
```
## 查看当前分支
```bash
git branch
```
## 分支合并
```bash
git merge -m '合并信息注释' <分支名>
```
## 删除分支
```bash
# 删除已合并的分支
git branch -d <分支名>
# 强制删除分支
git branch -D <分支名>
```
## 撤销一个合并
```bash
git reset --hard HEAD^
```
## 显示所有提交
```bash
git log
git log --stat
```
## 格式化日志输出
```bash
git log --pretty=oneline
git log --pretty=short
git log --graph --pretty=oneline
```
## 日志排序
```bash
git log --pretty=format:'%h : %s' --topo-order --graph
```
* \--reverse 参数来逆向显示所有提交日志
## Git 的基本流程如下:
1. 创建或修改文件
2. 使用 git add 命令添加新创建或修改的文件到本地的缓存区(Index)
3. 使用 git commit 命令提交到本地代码库
4. (可选,有的时候并没有可以同步的远端代码库)使用git push命令将本地代码库同步到远端代码库
## 小结
* git config:配置相关信息
* git clone:复制仓库
* git init:初始化仓库
* git add:添加更新内容到索引中
* git diff:比较内容
* git status:获取当前项目状况
* git commit:提交
* git branch:分支相关
* git checkout:切换分支
* git merge:合并分支
* git reset:恢复版本
* git log:查看日志
> 2020年07月23日发于简书 [文章地址](https://www.jianshu.com/p/f86b68244eb3)
---
id: 2
title: Linux 的 Git 学习笔记(二)
description: Linux 的 Git 学习笔记(二)
date: 2021-12-22 18:03:05
updated: 2021-12-22 18:03:05
author: Pengcc
tags:
- 版本控制
- git
categories:
- 版本控制
- git
keywords: git, Git, linux, Linux, 版本控制
---
## 比较修改或提交的内容
```bash
git diff
```
## 比较两分支的差别
```bash
git diff <分支 1> <分支 2>
```
## 仅比较某个文件或目录
```bash
git diff <分支名> <文件名或目录名>
```
## 统计那些文件有改动
```bash
git diff <分支名> --stat
```
## 合并不同目录的修改文件
```bash
git pull <绝对路径>
# 经常性
git remote add <目录名> <目录绝对路径>
# 从远程分支抓取最新修改消息
git fetch <目录绝对路径>
# 查看远程分支所做的修改
git log -p <分支名> -- <目录名/分支名>
# 合并分支
git merge <目录名/分支名>
克隆得到的更新
git pull
```
## 公共 git 仓库的克隆 SSh 地址
```bash
git clone ssh://服务器/账号/仓库名称
```
## 推送本地修改到公共 git 仓库
```bash
git push ssh://服务器仓库地址 master:master
git push ssh://服务器仓库地址 master
```
## 选择其中一个记录标志为 stable-1 的标签
```bash
# commit 的名称很长,通常我们只需要写前面 8 位即可
git tag <标签名> <commit前八位>
```
## 查看当前所有 tag
```bash
git tag
```
git tag 中使用 -a, -s 或是 -u 三个参数中任意一个,都会创建一个标签对象,并且需要一个标签消息来为 tag 添加注释。 如果没有 -m 或是 -F 这些参数,命令执行时会启动一个编辑器来让用户输入标签消息
```bash
git tag -a <标签名> <commit前八位> -m "标签信息"
```
> 2020年07月24日发于简书 [文章地址](https://www.jianshu.com/p/54628961ebb0)
---
id: 3
title: Linux 的 Git 学习笔记(三)
description: Linux 的 Git 学习笔记(三)
date: 2021-12-22 18:04:18
updated: 2021-12-22 18:04:18
author: Pengcc
tags:
- 版本控制
- git
categories:
- 版本控制
- git
keywords: git, Git, linux, Linux, 版本控制
---
## 忽略文件
可以在顶层工作目录中添加一个叫 .gitignore 的文件,来告诉 Git 系统要忽略掉哪些文件,下面是文件内容的示例。\
以'#' 开始的行,被视为注释。忽略掉所有文件名是 foo.txt 的文件,.gitignore 的文件内容为:
```bash
foo.txt
# 忽略所有生成的 html 文件:
*.html
# 如果 foo.html 这个文件不能忽略,可以写个例外:
!foo.html
# 忽略所有 .o 和 .a 文件:
*.[oa]
```
## 基于远程分支origin创建一个mywork分支
```bash
git checkout -b mywork origin
```
## 使mywork分支历史看起来没有任何合并
```bash
git checkout mywork
git rebase origin
```
## git rebase遇到冲突,git add命令解决完后可直接执行
```bash
git rebase --continue
# 中止操作
git rebase --abrot
```
## git索引
```bash
git add -i
```
当你正在做一项复杂的工作时, 发现了一个和当前工作不相关但是又很讨厌的 bug. 你这时想先修复 bug 再做手头的工作, 那么就可以用 git stash 来保存当前的工作状态, 等你修复完 bug 后,执行反储藏(unstash)操作就可以回到之前的工作里。
```bash
git stash save "work in progress for foo feature"
```
## 修复工作
```bash
git commit -a -m "blorpl: typofix"
```
## 返回原工作状态
```bash
git stash apply
```
## 显示储存队列
```bash
git stash list
```
## 使用某个储存
```bash
git stash apply stash@{标号}
```
## 清空储存列表
```bash
git stash clear
```
> 2020年07月25日发于简书 [文章地址](http://www.jianshu.com/p/8a4239e77370)
---
id: 4
title: Linux 的 Git 学习笔记(四)
description: Linux 的 Git 学习笔记(四)
date: 2021-12-22 18:04:26
updated: 2021-12-22 18:04:26
author: Pengcc
tags:
- 版本控制
- git
categories:
- 版本控制
- git
keywords: git, Git, linux, Linux, 版本控制
---
## 追踪分支
```bash
git branch --track experimental origin/experimental
```
它会自动从 origin 抓取(fetch)内容,再把远程的 origin/experimental 分支 合并进(merge)本地的 experimental 分支\
当要把修改推送(push)到 origin 时,它会将你本地的 experimental 分支中的修改推送到origin 的 experimental 分支里,而无需指定它(origin)
```bash
git pull experimental
```
## 在git库内搜素字段
```bash
git grep <字段>
# 显示行号
git grep -n <字段>
# 只显示文件名
git grep --name-only <字段>
# 每个文件中有多少行匹配该字段
git grep -c xmmap <字段>
# 查找在某个特定版本中的字段
git grep <字段> <版本号>
```
## 回到上次提交状态
```bash
git reset --hard HEAD^
```
## 恢复某个文件
```bash
git checkout -- <文件名>
```
## 撤销最近一次提交
```bash
git revert HEAD
```
## 撤销上上次提交
```bash
git revert HEAD^
```
## 修改上次提交的错误
```bash
git commit --amend
```
## 压缩操作
```bash
git gc
```
## 进行仓库一致性检查
```bash
git fsck
```
> 2020年07月26日发于简书 [文章地址](https://www.jianshu.com/p/b62d037f6c75)
---
id: 5
title: MongoDB的安装配置(ZIP版)
description: MongoDB的安装配置(ZIP版)
date: 2021-12-22 18:23:44
updated: 2021-12-22 18:23:44
tags:
- mongodb
- windows
categories:
- Windows软件安装配置
- 数据库
keywords: mongodb, MongoDB, 数据库, NoSQL, nosql, windows, Windows
---
## 一、 准备工作
从MongoDB官网下载MongoDB的ZIP安装包
官网链接:<https://www.mongodb.com/try/download/community>
选择MongoDB Community Server,选择对应版本、平台
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note1-1.png)
下载完成后解压到自己的路径
## 二、 文件配置与安装
### 1. 文件配置
进入解压后的文件夹,新建data和log文件夹,并在log文件夹下,新建mongo.log空文件
新建mongo.conf文件与bin文件夹同级
mongo.conf写入以下内容
```bash
# 数据库路径
dbpath=E:\other_dev\mongodb\data
# 日志输出文件路径
logpath=E:\other_dev\mongodb\logs\mongo.log
# 错误日志采用追加模式
logappend=true
# 启用日志文件,默认启用
journal=true
# 这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
quiet=true
# 端口号 默认为27017
port=27017
```
**注:dbpath和logpath根据自己的具体路径进行修改**
### 2. 安装
从bin文件夹下进入命令行执行
```bash
mongod --config "E:\other_dev\mongodb\mongo.conf"
```
**注:引号内的路径换成刚刚配置文件的路径**
执行后没有任何反应,则关掉该窗口
## 三、 运行测试
### 1. 从bin文件夹下进入命令行执行
```bash
mongod --dbpath E:\other_dev\mongodb\data
```
**注:引号内的路径换成自己存放数据库的路径**
### 2. 启动完成后,不要关掉该窗口,重新从bin文件夹下进入命令行执行
```bash
mongo
```
进入mongo命令行模式
> 2021年06月19日发于简书 [文章地址](https://www.jianshu.com/p/4092643aa3c3)\
> 2021年07月13日发于知乎 [文章地址](https://zhuanlan.zhihu.com/p/389247092)\
> 2021年07月31日发于CSDN [文章地址](https://blog.csdn.net/qq_46106320/article/details/119269582)
---
id: 6
title: NodeJS安装配置(ZIP版)
description: NodeJS安装配置(ZIP版)
date: 2021-12-22 18:25:36
updated: 2021-12-22 18:25:36
tags:
- nodejs
- windows
categories:
- Windows软件安装配置
- 前端
keywords: node, Node, nodejs, NodeJS, windows, Windows
---
## 一、下载NodeJS的ZIP安装包
根据系统版本去NodeJS官网下载ZIP安装包
NodeJS官网:<https://nodejs.org/en/>
下载完成,解压到指定路径
## 二、配置和安装
### 1. 配置node的缓存路径和全模块路径
在node安装目录下新建node\_cache和node\_global两个文件夹
输入以下命令
```bash
npm config set prefix "D:\project\tools\node-v14.16.1-win-x64\node_global"
npm config set cache "D:\project\tools\node-v14.16.1-win-x64\node_cache"
```
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note2-1.png)
**注意:引号内的路径根据自己的具体路径进行修改**
### 2. 配置环境变量
创建环境变狼NODE,node的安装路径
在Path中添加%NODE%,%NODE%\node\_global
检查node版本,输入命令node –v
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note2-2.png)
### 3. 安装全模块
输入命令npm install express –g
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note2-3.png)
## 三、测试运行
创建一个项目进行测试
输入命令express –t ejs demo
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note2-4.png)
安装依赖,运行项目
输入命令cd demo,npm install,npm start
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note2-5.png)
> 2021年06月24日发于简书 [文章地址](https://www.jianshu.com/p/e3e000c67c81)\
> 2021年07月19日发于知乎 [文章地址](https://zhuanlan.zhihu.com/p/389704886)\
> 2021年09月15日发于CSDN [文章地址](https://blog.csdn.net/qq_46106320/article/details/120306455)
---
id: 7
title: Redis安装配置(ZIP版)
description: Redis安装配置(ZIP版)
date: 2021-12-22 18:25:55
updated: 2021-12-22 18:25:55
tags:
- redis
- windows
categories:
- Windows软件安装配置
- 数据库
keywords: redis, Redis, windows, Windows, 数据库
---
## 一、下载Redis安装包
根据系统版本下载Redis安装包
Linux版本下载地址:<https://redis.io/download>
Windows版本下载地址:<https://github.com/microsoftarchive/redis/releases>
本文以Windows为例,下载完成后解压到自己的路径
## 二、文件配置与安装
### 1. 临时服务安装
进入Redis解压后的目录,并在该目录下启动命令行,输入以下命令
```bash
redis-server.exe redis.windows.conf
```
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note3-1.png)
打开Redis解压后的目录中的redis-cli.exe,运行redis客户端,上一个窗口不能关闭
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note3-2.png)
使用临时服务安装,不会出现在Windows服务中
### 2. 默认服务安装
进入Redis解压后的目录,并在该目录下启动命令行,输入以下命令
```bash
redis-server.exe --service-install redis.windows.conf --loglevel verbose
```
**注:一定要把临时服务关闭,否则安装不上**
启动/暂停/卸载服务
```bash
# 启动
redis-server.exe --service-start
# 暂停
redis-server.exe --service-stop
# 卸载
redis-server.exe --service-uninstall
```
使用默认服务安装,会出现在Windows服务中
### 3. 自定义服务安装
进入Redis解压后的目录,并在该目录下启动命令行,输入以下命令
```bash
redis-server.exe --service-install redis.windows.conf --Service-name RedisServer1 --loglevel verbose
```
启动/暂停/卸载服务
```bash
# 启动
redis-server.exe --service-start --Service-name RedisServer1
# 暂停
redis-server.exe --service-stop --Service-name RedisServer1
# 卸载
redis-server.exe?--service-uninstall --Service-name RedisServer1
```
使用自定义服务安装,可以重命名服务名并会出现在Windows服务中
> 2021年07月02日发于简书 [文章地址](https://www.jianshu.com/p/ca829a56f00d)\
> 2021年07月28日发于知乎 [文章地址](https://zhuanlan.zhihu.com/p/389705449)
---
id: 8
title: Erlang和RabbitMQ(ZIP版)安装配置
description: Erlang和RabbitMQ(ZIP版)安装配置
date: 2021-12-22 18:26:45
updated: 2021-12-22 18:26:45
tags:
- erlang
- rabbitMQ
- windows
categories:
- Windows软件安装配置
- 中间件
keywords: erlang, Erlang, rabbitMQ, RabbitMQ, 中间件, 消息队列, windows, Windows
---
## 一、下载Erlang和RabbitMQ安装包
在Erlang官网和RabbitMQ官网,根据系统版本下载Erlang和RabbitMQ安装包
Erlang官网:<https://www.erlang.org>
RabbitMQ官网:<http://www.rabbitmq.com>
RabbitMQ压缩包下载地址:<https://www.rabbitmq.com/install-windows-manual.html>
RabbitMQ压缩包下载后解压到指定目录下
## 二、Erlang安装配置
### 1. 安装
双击运行exe文件,指定安装路径,等待安装完成
### 2. 配置
创建环境变量ERLANG\_HOME,erl的安装路径
在Path中添加%ERLANG\_HOME%\bin
打开命令行,输入erl
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note4-1.png)
Erlang配置完成
## 三、RabbitMQ安装配置
### 1. 配置
创建环境变量RABBITMQ\_SERVER,rabbitMQ的安装目录
在Path中添加%RABBITMQ\_SERVER%\sbin
打开命令行输入rabbitmqctl status
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note4-2.png)
说明rabbitMQ未启动
安装插件,输入命令rabbitmq-plugins.bat enable rabbitmq\_management
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note4-3.png)
出现该界面则安装成功
若出现问题如下
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note4-4.png)
解决方法:将 `C:\Users\Lenovo\.erlang.cookie` 同步至 `C:\Windows\System32\config\systemprofile\.erlang.cookie`
同时删除:`C:\Users\Lenovo\AppData\Roaming\RabbitMQ` 目录
### 2. 测试运行
输入命令rabbitmq-server.bat
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note4-5.png)
rabbitmq启动成功,浏览器中[http://localhost:15672](http://localhost:15672/)进行访问
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note4-6.png)
输入用户名:guest,密码:guest进入控制台
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note4-7.png)
输入命令rabbitmqctl status
![image.png](https://13812700839.github.io/MyImageBed/images/repository/installConfigNote/note4-8.png)
RabbitMQ部署完成
> 2021年07月03日发于简书 [文章地址](https://www.jianshu.com/p/c5d7481c6c51)\
> 2021年07月31日发于知乎 [文章地址](https://zhuanlan.zhihu.com/p/389703513)
---
title: About
layout: about
---
\ No newline at end of file
---
title: 文章分类
layout: category
---
\ No newline at end of file
---
title: 文章标签
layout: tag
---
---
title: Friends
layout: friends
---
\ No newline at end of file
---
title: Project
layout: project
---
_site/
.sass-cache/
.jekyll-metadata
.DS_Store
node_modules
package-lock.json
.github/
publish.sh
node_modules
node_modules
package-lock.json
\ No newline at end of file
MIT License
Copyright (c) 2017 xaoxuu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<p align="center">
<a href='https://volantis.js.org'><img src='https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/Logo-Cover@3x.png' height='120px'></a>
</p>
[![](https://img.shields.io/npm/v/hexo-theme-volantis.svg?style=flat-square)](https://www.npmjs.com/package/hexo-theme-volantis)
## Getting Started
Check your environment:
```yaml
Hexo: 4.2 ~ 5.x
hexo-cli: 3.1 ~ 4.x
node.js: 12.16 LTS ~ latest LTS
npm: 6.13 ~ latest LTS
```
Edit your `_config.yml`:
```yaml
theme: volantis
```
Install Volantis in terminal:
```bash
npm i hexo-theme-volantis
```
## Usage
See docs: https://volantis.js.org
or: https://volantis.vercel.app
## Examples
See examples: https://volantis.js.org/examples/
Add your blog to examples page: https://github.com/volantis-x/examples/issues/
## Feedback
Feedback to developer: https://github.com/volantis-x/hexo-theme-volantis/issues/
Discuss with other users: https://github.com/volantis-x/hexo-theme-volantis/discussions/
## Screenshot
![](https://i.loli.net/2020/03/18/f5PQlWisvm9zbgK.jpg)
![](https://i.loli.net/2020/03/18/XWBGf95E2t1bdnl.jpg)
![](https://i.loli.net/2020/03/18/1TpiUwhuskGm5SV.png)
![](https://i.loli.net/2020/03/18/LZwBtR5YO4zQH9A.png)
![](https://i.loli.net/2020/03/18/ySw8zGHRBrDtUg7.png)
![](https://i.loli.net/2020/03/18/5QTMYsScOz41Vhg.png)
此差异已折叠。
navbar:
archive: Archive
category: Category
tag: Tag
post:
pin: Top
readmore: Read More
readoriginal: Read Original
wordcount: '%s words'
duration: '%s min'
comments: Comments
comments_load: Load %s
comments_check: Checking if %s is accessible...
comments_placeholder: Unable to load %s, please make sure your network can access.
copy_button: Copy
copy_success: Copied
copy_failure: Copy failed
updated: updated at
prev_page: Previous
next_page: Next
copyright:
author: Post author
link: Post link
license_title: Copyright Notice
license_content: "All articles in this blog are licensed under %s unless stating additionally."
footer:
license: 'Blog content follows the [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)'
use: Use
theme: as theme
total_views: total visits
total_visitors: total visitors
times: times
site_source: Uses %s as theme. You can find [source](%s) in %s.
site_views: The visits is about %s, and the visitors is about %s.
symbol:
comma: ", "
period: ". "
colon: ": "
brackets_l: "("
brackets_r: ")"
rightmenu:
back: "Back"
forward: "Forward"
reload: "Reload"
search_word: "Site Search"
copy_text: "Copy Text"
copy_image_src: "Copy Image Link"
copy_link: "Copy Link"
open_in_new_tab: "Open Link in New Tab"
kill:
title: "Sorry, your browser cannot access this site"
more: "Learn more >"
noscript: "This page requires browser support (enable) JavaScript"
ie: "Microsoft has terminated support for Internet Explorer (IE) 10 and earlier versions in 2016. <br/>There are great security risks to continue using it. Please use contemporary mainstream browsers to access."
navbar:
archive: 归档
category: 分类
tag: 标签
post:
pin: 置顶
readmore: 阅读全文
readoriginal: 去源站阅读
wordcount: '字数:%s 字'
duration: '时长:%s 分钟'
comments: 评论
comments_load: 点击加载 %s 评论
comments_check: 正在检查 %s 能否访问...
comments_placeholder: 无法加载 %s 评论系统,请确保您的网络能够正常访问。
copy_button: 复制
copy_success: 复制成功
copy_failure: 复制失败
updated: 更新于
prev_page: 上一页
next_page: 下一页
copyright:
author: 本文作者
link: 本文链接
license_title: 版权声明
license_content: "本博客所有文章除特别声明外,均采用 %s 许可协议。转载请注明出处!"
footer:
license: '博客内容遵循 [署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)'
use: 本站使用
theme: 作为主题
total_views: 总访问量为
total_visitors: 总访客量
times:
site_source: 本站使用 %s 作为主题,您可以在 %s 找到[本站源码](%s)。
site_views: 总访问量约为 %s 次,访问人数约为 %s 人。
symbol:
comma: ","
period: "。"
colon: ":"
brackets_l: "("
brackets_r: ")"
rightmenu:
back: "返回"
forward: "前进"
reload: "刷新"
search_word: "站内搜索"
copy_text: "复制文本"
copy_paste: "粘贴文本"
copy_select: "全选文本"
copy_cut: "剪切文本"
copy_image_src: "复制图片地址"
copy_image_file: "复制图片文件"
copy_link: "复制链接"
open_in_new_tab: "在新标签页打开"
kill:
title: "抱歉,您的浏览器无法访问本站"
more: "了解详情 >"
noscript: "本页面需要浏览器支持(启用)JavaScript"
ie: "微软已经于2016年终止了对 Internet Explorer (IE) 10 及更早版本的支持,<br/>继续使用存在极大的安全隐患,请使用当代主流的浏览器进行访问。"
navbar:
archive: 歸檔
category: 分類
tag: 標籤
post:
pin: 置頂
readmore: 閱讀全文
readoriginal: 去源站閱讀
wordcount: '字數:%s字'
duration: '時長:%s分鐘'
comments: 評論
comments_load: 點擊加載 %s 評論
comments_check: 正在檢查 %s 能否訪問...
comments_placeholder: 無法加載 %s 評論系統,請確保您的網絡能夠正常訪問。
copy_button: 複製
copy_success: 複製成功
copy_failure: 複製失敗
updated: 更新於
prev_page: 上一頁
next_page: 下一頁
copyright:
author: 本文作者
link: 文章連結
license_title: 版權聲明
license_content: "本網誌所有文章除特別聲明外,均採用 %s 許可協議。轉載請註明出處!"
footer:
license: '博客內容遵循 [姓名標示-非商業性-相同方式分享 4.0 國際 (CC BY-NC-SA 4.0) 協議](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh_TW)'
use: 本站使用
theme: 作為主題
total_views: 總訪問量為
total_visitors: 總訪客量為
times:
site_source: 本站使用 %s 作為主題,您可以在 %s 找到[本站源碼](%s)。
site_views: 總訪問量約為 %s 次,訪問人數約為 %s 人。
symbol:
comma: ","
period: "。"
colon: ":"
brackets_l: "("
brackets_r: ")"
rightmenu:
back: "返回"
forward: "前进"
reload: "刷新"
search_word: "站內搜索"
copy_text: "複製文本"
copy_image_src: "複製圖片地址"
copy_link: "複製鏈接"
open_in_new_tab: "在新標籤頁打開"
kill:
title: "抱歉,您的瀏覽器無法訪問本站"
more: "了解詳情 >"
noscript: "本頁面需要瀏覽器支持(啟用)JavaScript"
ie: "微軟已經於2016年終止了對 Internet Explorer (IE) 10 及更早版本的支持,<br/>繼續使用存在極大的安全隱患,請使用當代主流的瀏覽器進行訪問。"
<%- partial('_pre') %>
<div id="l_main" class="no_sidebar">
<%- partial('_partial/article', {post: page, index: false}) %>
</div>
<%
let author = theme.article.body.meta_library.author;
let aid = post.author;
if (aid && site.data && site.data.author && (aid in site.data.author)) {
author = site.data.author[aid];
}
%>
<div class='new-meta-item author' itemprop="author" itemscope itemtype="http://schema.org/Person">
<a itemprop="url" class='author' href="<%- author.url %>" rel="nofollow">
<img itemprop="image" src="<%- author.avatar %>">
<p itemprop="name"><%- author.name %></p>
</a>
</div>
<% if (post.categories && post.categories.length){ %>
<div class='new-meta-item category'>
<i class="<%- theme.article.body.meta_library.category.icon %> fa-fw" aria-hidden="true"></i>
<%- list_categories(post.categories, {
show_count: false,
separator: '<span class="sep"></span>',
style: 'none'
}) %>
<% for(cat of post.categories.toArray()){ %>
<span hidden itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="<%- url_for(cat.path) %>" itemprop="url"><span itemprop="name"><%- cat.name %></span></a>
</span>
<% } %>
</div>
<% } %>
<% if (theme.analytics && theme.analytics.leancloud && theme.analytics.leancloud.app_id) { %>
<div class="new-meta-item browse leancloud">
<a class='notlink'>
<%
var path = post.path || page.path;
if (path.length > 9 && (path.substring(path.length - 10) == 'index.html')) {
path = path.substring(0, path.length - 10);
}
%>
<div id="lc-pv" data-title="<%- post.title || page.title %>" data-path="<%- url_for(path) %>">
<i class="<%- theme.article.body.meta_library.counter.icon %> fa-fw" aria-hidden="true"></i>
<span id='number'><i class="fas fa-circle-notch fa-spin fa-fw" aria-hidden="true"></i></span>
<%- theme.article.body.meta_library.counter.unit %>
</div>
</a>
</div>
<% } else if (theme.analytics.busuanzi) { %>
<div class="new-meta-item browse busuanzi">
<a class='notlink'>
<i class="<%- theme.article.body.meta_library.counter.icon %> fa-fw" aria-hidden="true"></i>
<p>
<span id="busuanzi_value_page_pv">
<i class="fas fa-circle-notch fa-spin fa-fw" aria-hidden="true"></i>
</span>
<%- theme.article.body.meta_library.counter.unit %>
</p>
</a>
</div>
<% } else if (
(theme.comments.service=='valine' && theme.comments.valine.visitor) ||
(theme.comments.service=='minivaline' && theme.comments.minivaline.visitor) ||
(theme.comments.service=='waline' && theme.comments.waline.visitor)) { %>
<div class="new-meta-item browse">
<a class='notlink'>
<i class="<%- theme.article.body.meta_library.counter.icon %> fa-fw" aria-hidden="true"></i>
<%
var path = post.path || page.path;
if (path.length > 9 && (path.substring(path.length - 10) == 'index.html')) {
path = path.substring(0, path.length - 10);
}
%>
<span id="<%- url_for(path) %>" class="leancloud_visitors" data-flag-title="<%- post.title || page.title %>">
<p>
<span class="leancloud-visitors-count"></span>
</p>
</span>
</a>
</div>
<% } else if (theme.comments.service=='twikoo' && !!page.comments) { %>
<div class="new-meta-item browse">
<a class='notlink'>
<i class="<%- theme.article.body.meta_library.counter.icon %> fa-fw" aria-hidden="true"></i>
<p>
<span id="twikoo_visitors"></span>
</p>
</span>
</a>
</div>
<% } %>
<div class="new-meta-item date" itemprop="dateCreated datePublished" datetime="<%- moment(post.date).format() %>">
<a class='notlink'>
<i class="<%- theme.article.body.meta_library.date.icon %> fa-fw" aria-hidden="true"></i>
<p><%- theme.article.body.meta_library.date.title + date(post.date, theme.article.body.meta_library.date.format) %></p>
</a>
</div>
<% if(post.music && post.music.enable != false){ %>
<%- partial('../_plugins/aplayer/layout', {post: post, where: 'meta'}) %>
<% } %>
<% if (theme.article.body.meta_library.share) { %>
<%- partial('../_plugins/share/layout') %>
<% } %>
<% if (post.tags && post.tags.length) { %>
<%
var items = [];
var hidden_items = [];
post.tags.each(function(item){
items.push('<div class="new-meta-item meta-tags"><a class="tag" href="'+url_for(item.path)+'" rel="nofollow"><i class="' + theme.article.body.meta_library.tags.icon + ' fa-fw" aria-hidden="true"></i><p>' + item.name + '</p></a></div>');
hidden_items.push(item.name);
});
%>
<%- items.join(' ') %>
<span hidden itemprop="keywords"><%- hidden_items.join(' ') %></span>
<% } %>
<% if(post.thumbnail && post.thumbnail.length){ %>
<a title='<%- post.title %>' href='<%- url_for(post.link || post.path) %>'>
<img class='thumbnail' src='<%- post.thumbnail %>' itemprop="image">
</a>
<% } %>
<div class="new-meta-item date" itemprop="dateModified" datetime="<%- moment(post.updated).format() %>">
<a class='notlink'>
<i class="<%- theme.article.body.meta_library.updated.icon %> fa-fw" aria-hidden="true"></i>
<p><%- theme.article.body.meta_library.updated.title + date(post.updated, theme.article.body.meta_library.updated.format) %></p>
</a>
</div>
<% if (theme.comments.service == 'valine'){ %>
<div class="new-meta-item comments-count">
<%
var path = post.path || page.path;
if (path.length > 9 && (path.substring(path.length - 10) == 'index.html')) {
path = path.substring(0, path.length - 10);
}
%>
<a href="<%- url_for(path) %>#comments">
<i class="<%- theme.article.body.meta_library.valinecount.icon %> fa-fw"></i>
<span class="valine-comment-count" data-xid="<%- url_for(path) %>">0</span>
<span class="leancloud-comments-count">&nbsp;<%- theme.article.body.meta_library.valinecount.desc %></span>
</a>
</div>
<% } %>
<% if (theme.comments.service == 'waline'){ %>
<div class="new-meta-item comments-count">
<%
var path = post.path || page.path;
if (path.length > 9 && (path.substring(path.length - 10) == 'index.html')) {
path = path.substring(0, path.length - 10);
}
%>
<a href="<%- url_for(path) %>#comments">
<i class="<%- theme.article.body.meta_library.walinecount.icon %> fa-fw"></i>
<span id="<%- url_for(path) %>" class="waline-comment-count"></span>
<span class="leancloud-comments-count">&nbsp;<%- theme.article.body.meta_library.walinecount.desc %></span>
</a>
</div>
<% } %>
<% if (theme.plugins.wordcount.enable) { %>
<div class="new-meta-item wordcount">
<a class='notlink'>
<i class="<%- theme.article.body.meta_library.wordcount.icon_wordcount %> fa-fw" aria-hidden="true"></i>
<p><%- __('post.wordcount', wordcount(post.content))%></p>
</a>
</div>
<div class="new-meta-item readtime">
<a class='notlink'>
<i class="<%- theme.article.body.meta_library.wordcount.icon_duration %> fa-fw" aria-hidden="true"></i>
<p><%- __('post.duration', min2read(post.content))%></p>
</a>
</div>
<% } %>
<div class='cover-body'>
<div class='top'>
<% if (theme.cover.logo) { %>
<img no-lazy class='logo' src='<%- url_for(theme.cover.logo) %>'/>
<% } %>
<% if (theme.cover.title) { %>
<p class="title"><%- theme.cover.title ? theme.cover.title : config.title %></p>
<% } %>
<% if (theme.cover.subtitle) { %>
<p class="subtitle"><%- theme.cover.subtitle%></p>
<% } %>
</div>
<div class='bottom'>
<div class='menu navigation'>
<div class='list-h'>
<% if (theme.cover.features) { %>
<% (theme.cover.features || []).forEach(function(value){ %>
<a href="<%= url_for(value.url) %>"
<% if (value.rel) { %>
rel="<%- value.rel %>"
<% } %>
<% if (value.target) { %>
target="<%- value.target %>"
<% } %>
active-action="action-<%= url_for(value.url).replace(/\/|%|\./g, "")?url_for(value.url).replace(/\/|%|\./g, ""):"home" %>">
<% if (value.img) { %><img src='<%= value.img %>'><% } else if (value.icon) { %><i class='<%= value.icon %> fa-fw'></i><% } %><p><%- value.name %></p>
</a>
<%})%>
<% } %>
</div>
</div>
</div>
</div>
<div class='cover-body'>
<div class='top'>
<% if (theme.cover.logo) { %>
<img no-lazy class='logo' src='<%- url_for(theme.cover.logo) %>'/>
<% } %>
<% if (theme.cover.title) { %>
<p class="title"><%- theme.cover.title ? theme.cover.title : config.title %></p>
<% } %>
<% if (theme.cover.subtitle) { %>
<p class="subtitle"><%- theme.cover.subtitle%></p>
<% } %>
</div>
<div class='bottom'>
<div class='menu navigation'>
<div class='list-h'>
<% if (theme.cover.features) { %>
<% (theme.cover.features || []).forEach(function(value){ %>
<a href="<%= url_for(value.url) %>"
<% if (value.rel) { %>
rel="<%- value.rel %>"
<% } %>
<% if (value.target) { %>
target="<%- value.target %>"
<% } %>
active-action="action-<%= url_for(value.url).replace(/\/|%|\./g, "")?url_for(value.url).replace(/\/|%|\./g, ""):"home" %>">
<% if (value.img) { %><img src='<%= value.img %>'><% } else if (value.icon) { %><i class='<%= value.icon %> fa-fw'></i><% } %><p><%- value.name %></p>
</a>
<%})%>
<% } %>
</div>
</div>
</div>
</div>
<div class='cover-body'>
<div class='top'>
<% if (theme.cover.logo) { %>
<img no-lazy class='logo' src='<%- url_for(theme.cover.logo) %>'/>
<% } %>
<% if (theme.cover.title) { %>
<p class="title"><%- theme.cover.title ? theme.cover.title : config.title %></p>
<% } %>
<% if (theme.cover.subtitle) { %>
<p class="subtitle"><%- theme.cover.subtitle%></p>
<% } %>
</div>
<div class='bottom'>
<div class='menu navigation'>
<div class='list-h'>
<% if (theme.cover.features) { %>
<% (theme.cover.features || []).forEach(function(value){ %>
<a href="<%= url_for(value.url) %>"
<% if (value.rel) { %>
rel="<%- value.rel %>"
<% } %>
<% if (value.target) { %>
target="<%- value.target %>"
<% } %>
active-action="action-<%= url_for(value.url).replace(/\/|%|\./g, "")?url_for(value.url).replace(/\/|%|\./g, ""):"home" %>">
<% if (value.img) { %><img src='<%= value.img %>'><% } else if (value.icon) { %><i class='<%= value.icon %> fa-fw'></i><% } %><p><%- value.name %></p>
</a>
<%})%>
<% } %>
</div>
</div>
</div>
</div>
<% if (theme.plugins.parallax.enable) { %>
<div id="parallax-window"></div>
<% } else if (theme.plugins.lazyload && theme.plugins.lazyload.enable) { %>
<div class='cover-bg lazyload placeholder' data-bg="<%- theme.cover.background %>"></div>
<% } else { %>
<div class='cover-bg' style='background-image:url(<%- theme.cover.background %>)'></div>
<% } %>
<%- partial(theme.cover.layout_scheme) %>
\ No newline at end of file
<div class='cover-body'>
<div class='top'>
<% if (theme.cover.logo) { %>
<img no-lazy class='logo' src='<%- url_for(theme.cover.logo) %>'/>
<% } %>
<% if (theme.cover.title) { %>
<p class="title"><%- theme.cover.title ? theme.cover.title : config.title %></p>
<% } %>
<% if (theme.cover.subtitle) { %>
<p class="subtitle"><%- theme.cover.subtitle%></p>
<% } %>
</div>
<div class='bottom'>
<% if (theme.search.enable === true) { %>
<div class="m_search">
<form name="searchform" class="form u-search-form">
<input type="text" class="input u-search-input" placeholder="<%- theme.cover && theme.cover.search %>" />
<i class="icon fas fa-search fa-fw"></i>
</form>
</div>
<% } %>
<div class='menu navigation'>
<div class='list-h'>
<% if (theme.cover.features) { %>
<% (theme.cover.features || []).forEach(function(value){ %>
<a href="<%= url_for(value.url) %>"
<% if (value.rel) { %>
rel="<%- value.rel %>"
<% } %>
<% if (value.target) { %>
target="<%- value.target %>"
<% } %>
active-action="action-<%= url_for(value.url).replace(/\/|%|\./g, "")?url_for(value.url).replace(/\/|%|\./g, ""):"home" %>">
<% if (value.icon) { %><i class='<%= value.icon %> fa-fw'></i><% } %><p><%- value.name %></p>
</a>
<%})%>
<% } %>
</div>
</div>
</div>
</div>
<% if (site.posts && site.posts.length > 0) { %>
<section class="post-list">
<% if (!page.prev) { %>
<% if (is_home()) { %>
<% site.pages.each(function(post){ %>
<% if (post.pin) { %>
<% if (page.group == undefined || post.group == page.group) { %>
<div class='post-wrapper'>
<%- partial('post', {post: post}) %>
</div>
<% } %>
<% } %>
<% }) %>
<% site.posts.sort('date', -1).each(function(post){ %>
<% if (post.pin) { %>
<% if (page.group == undefined || post.group == page.group) { %>
<div class='post-wrapper'>
<%- partial('post', {post: post}) %>
</div>
<% } %>
<% } %>
<% }) %>
<% } else if (page.posts && page.posts.length > 0) { %>
<% page.posts.each(function(post){ %>
<% if (post.pin) { %>
<div class='post-wrapper'>
<%- partial('post', {post: post}) %>
</div>
<% } %>
<% }) %>
<% } %>
<% } %>
<% if (page.posts && page.posts.length > 0) { %>
<% page.posts.each(function(post){ %>
<% if (!post.pin) { %>
<div class='post-wrapper'>
<%- partial('post', {post: post}) %>
</div>
<% } %>
<% }) %>
<% } %>
</section>
<% if (page && page.posts) { %>
<% if (page.total > 1) { %>
<br>
<div class="prev-next">
<% if (page.prev != 0) { %>
<a class="prev" rel="prev" href="<%= url_for(page.prev_link) %>">
<section class="post prev white-box <%- theme.custom_css.body.effect.join(' ') %>" >
<i class="fas fa-chevron-left" aria-hidden="true"></i>&nbsp;<%- __('post.prev_page') %>&nbsp;
</section>
</a>
<% } %>
<p class="current">
<%= page.current%> / <%= page.total%>
</p>
<% if (page.next != 0) { %>
<a class="next" rel="next" href="<%= url_for(page.next_link) %>">
<section class="post next white-box <%- theme.custom_css.body.effect.join(' ') %>">
&nbsp;<%- __('post.next_page') %>&nbsp;<i class="fas fa-chevron-right" aria-hidden="true"></i>
</section>
</a>
<% } %>
</div>
<% } %>
<% } %>
<% } %>
<article itemscope itemtype="http://schema.org/Article" class="article post white-box reveal md <%- theme.custom_css.body.effect.join(' ') %> article-type-<%= post.layout %>" id="<%= post.layout %>" itemscope itemprop="blogPost">
<link itemprop="mainEntityOfPage" href="<%- post.permalink %>">
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="<%- config.title %>">
</span>
<%- partial('meta', {post: post, position: 'top'}) %>
<div id="layoutHelper-page-plugins"></div>
<div id="post-body" itemprop="articleBody">
<%- post.content %>
</div>
<% if (page.link) { %>
<div class='div-ori-link'>
<a class='ori-link' href='<%- url_for(post.link || post.path) %>'>
<%- post.link ? __('post.readoriginal') : __('post.readmore') %>
</a>
</div>
<% } %>
<% if (['post','docs'].includes(page.layout)) { %>
<% let footer_widget = theme.article.body.footer_widget; %>
<div class='footer'>
<% if (page.references && page.references.length > 0) { %>
<div class='references'>
<section class='header'>
<% if (footer_widget.references.icon) { %>
<i class="<%- footer_widget.references.icon %> fa-fw" aria-hidden="true"></i>
<% } %>
<span><%- footer_widget.references.title %></span>
</section>
<section class='body'>
<ul>
<% (page.references||[]).forEach(function(row){ %>
<li>
<a href="<%- url_for(row.url) %>" rel="external nofollow noopener noreferrer" target="_blank">
<%- row.title || url_for(row.url) %>
</a>
</li>
<% }) %>
</ul>
</section>
</div>
<% } %>
<% if (['post'].includes(page.layout) && footer_widget.related_posts && footer_widget.related_posts.enable == true) { %>
<%-
htmlGenerator(
popular_posts_json({ maxCount: footer_widget.related_posts.max_count , ulClass: 'vlts-rps' , PPMixingRate: 0.2 , isImage: true , isExcerpt: true} , post )
)
%>
<% } %>
<% if (['post'].includes(page.layout) && footer_widget.copyright && footer_widget.copyright.enable == true && post.copyright != false) { %>
<div class='copyright'>
<blockquote>
<% (footer_widget.copyright.content||[]).forEach(function(row){ %>
<% if (row == 'permalink') { %>
<p><%- footer_widget.copyright.permalink %><a href=<%- page.permalink %>><%- page.permalink %></a></p>
<% } else { %>
<%- markdown(row) %>
<% } %>
<% }) %>
</blockquote>
</div>
<% } %>
<% if (['post'].includes(page.layout) && footer_widget.donate && footer_widget.donate.enable == true) { %>
<div class='donate'>
<div class='imgs'>
<% (footer_widget.donate.images||[]).forEach(function(url){ %>
<img src='<%- url_for(url) %>'>
<% }) %>
</div>
</div>
<% } %>
</div>
<% } %>
<% if (['page', 'post', 'docs'].includes(post.layout)) { %>
<%- partial('meta', {post: post, position: 'bottom'}) %>
<% } %>
<% if ((post.group != undefined) && (post.order != undefined)) { %>
<%
let prev = new Object();
let next = new Object();
site.pages.each(function(p){
if ((p.title || p.seo_title) && p.path && (p.group == post.group)) {
if (p.order < post.order && (p.order > prev.order || prev.order == undefined)) {
prev = {title: p.title || p.seo_title, exp: truncate(strip_html(p.content), {length: 100}), path: p.path, order: p.order};
}
if (p.order > post.order && (p.order < next.order || next.order == undefined)) {
next = {title: p.title || p.seo_title, exp: truncate(strip_html(p.content), {length: 100}), path: p.path, order: p.order};
}
}
})
%>
<% if (['docs'].includes(post.layout) && (prev || next)) { %>
<div class="prev-next">
<% if (prev.path) { %>
<a class='prev' href='<%- url_for(prev.path) %>'>
<p class='title'><i class="fas fa-chevron-left" aria-hidden="true"></i><%- prev.title || '' %></p>
<p class='content'><%- prev.exp %></p>
</a>
<% } %>
<% if (next.path) { %>
<a class='next' href='<%- url_for(next.path) %>'>
<p class='title'><%- next.title || '' %><i class="fas fa-chevron-right" aria-hidden="true"></i></p>
<p class='content'><%- next.exp %></p>
</a>
<% } %>
</div>
<% } %>
<% } %>
<% if (post.prev || post.next) { %>
<div class="prev-next">
<% if (post.prev) { %>
<a class='prev' href='<%- url_for(post.prev.path) %>'>
<p class='title'><i class="fas fa-chevron-left" aria-hidden="true"></i><%- post.prev.title || '' %></p>
<p class='content'><%- truncate(strip_html(page.prev.content), {length: 100}) %></p>
</a>
<% } %>
<% if (post.next) { %>
<a class='next' href='<%- url_for(post.next.path) %>'>
<p class='title'><%- post.next.title || '' %><i class="fas fa-chevron-right" aria-hidden="true"></i></p>
<p class='content'><%- truncate(strip_html(page.next.content), {length: 100}) %></p>
</a>
<% } %>
</div>
<% } %>
<!-- Custom Files postEnd begin-->
<%- volantis_inject('postEnd') %>
<!-- Custom Files postEnd end-->
</article>
<% if (page.comments == undefined || page.comments != false) { %>
<%- partial('../_plugins/comments/index') %>
<% } %>
<% if (post.categories && post.categories.length && post.categories.forEach){ %>
<%
var cats = [];
post.categories.forEach(function(cat){
cats.push('<a class="categories" href="'+url_for(cat.path)+'">' + cat.name + '</a>');
});
%>
<div class='metatag cats'>
<i class="fas fa-folder-open fa-fw" aria-hidden="true"></i>&nbsp;<%- cats.join('&nbsp;/&nbsp;') %>
</div>
<% } %>
<div id="l_cover">
<% if (theme.plugins.pjax.enable) { %>
<% if (theme.pjax_cover.enableCover) { %>
<!-- see: /layout/_partial/scripts/_ctrl/coverCtrl.ejs -->
<div id="<%- theme.pjax_cover.frontMatterCover %>" class='cover-wrapper <%- page.layout %> <%- theme.cover.layout_scheme %>' style="display: <%- theme.pjax_cover.coverWrapperDisplay %>;">
<%- partial("./_cover/layout") %>
<div id="scroll-down" style="display: <%- theme.pjax_cover.scrollDownDisplay %>;"><i class="fa fa-chevron-down scroll-down-effects"></i></div>
</div>
<% } %>
<% } else { %>
<% if (page.cover == true) { %>
<% if (is_home() && page.prev == 0 && theme.cover.height_scheme == 'full') { %>
<div class="cover-wrapper <%- page.layout %> <%- theme.cover.layout_scheme %>" id='full'>
<%- partial("./_cover/layout") %>
<div id="scroll-down"><i class="fa fa-chevron-down scroll-down-effects"></i></div>
</div>
<% } else { %>
<div class="cover-wrapper <%- page.layout %> <%- theme.cover.layout_scheme %>" id='half'>
<%- partial("./_cover/layout") %>
</div>
<% } %>
<% } %>
<% } %>
</div>
<% if (theme.site_footer) { %>
<%
var layout = theme.site_footer.layout;
if (config.theme_config && config.theme_config.footer && config.theme_config.footer.layout) {
layout = config.theme_config.footer.layout;
}
let theme_version = theme.info.theme_version
// 未发布的 alpha 版本
if (theme_version.indexOf("alpha")!=-1) {
theme_version = "dev"
}
%>
<footer class="footer clearfix" itemscope itemtype="http://schema.org/WPFooter">
<br><br>
<% layout.forEach(function(item){ %>
<% if (item == 'social') { %>
<br>
<div class="social-wrapper" itemprop="about" itemscope itemtype="http://schema.org/Thing">
<% (theme.site_footer.social||[]).forEach(function(value){ %>
<% if (value.url && (value.icon || value.img || value.avatar)) { %>
<a href="<%= url_for(value.url) %>"
class="social <%- value.icon %> flat-btn"
target="_blank"
rel="external nofollow noopener noreferrer" itemprop="url">
<% if (value.img) { %>
<img src="<%- value.img %>"/>
<% } else if (value.avatar) { %>
<img src="<%- value.avatar %>" style="border-radius:120px"/>
<% } %>
</a>
<% } %>
<% }) %>
</div>
<% } else if (item == 'aplayer') { %>
<div class="aplayer-container">
<%- partial('../_plugins/aplayer/layout', {post: null, where: 'footer'}) %>
</div>
<% } else if (item == 'license') { %>
<div><%- markdown(__('footer.license')) %></div>
<% } else if (item == 'info') { %>
<%- __('footer.use') %>
<a href="https://github.com/volantis-x/hexo-theme-volantis/tree/<%- theme_version %>" target="_blank" class="codename">Volantis</a>
<%- __('footer.theme') %>
<% // if (theme.analytics.busuanzi) { %><%- //__('symbol.comma') %>
<%- //__('footer.total_views') %>
<!-- <span id="busuanzi_value_site_pv"><i class="fas fa-circle-notch fa-spin fa-fw" aria-hidden="true"></i></span> -->
<%- //__('footer.times') %>
<% //} %>
<% } else if (item == 'source') { %>
<%- markdown(__('footer.site_source', '[Volantis](https://github.com/volantis-x/hexo-theme-volantis/tree/'+theme_version+')', 'GitHub', 'https://github.com/volantis-x/volantis-docs')) %>
<% } else if (item == 'copyright') { %>
<div class='copyright'>
<%- markdown(theme.site_footer.copyright) %>
</div>
<% } else { %>
<% if (item in theme.site_footer) { %>
<div><%- markdown(theme.site_footer[item]) %></div>
<% } %>
<% } %>
<% }) %>
<!-- Custom Files footer begin-->
<%- volantis_inject('footer') %>
<!-- Custom Files footer end-->
</footer>
<% } %>
<head hexo-theme='https://github.com/volantis-x/hexo-theme-volantis/tree/<%- theme.info.theme_version %>'>
<%- meta_generator() %>
<meta charset="utf-8">
<!-- SEO相关 -->
<%- generate_seo(theme, page) %>
<%- autoCanonical(config, page) %>
<!-- 渲染优化 -->
<meta http-equiv='x-dns-prefetch-control' content='on' />
<link rel='dns-prefetch' href='https://cdn.jsdelivr.net'>
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
<meta name="renderer" content="webkit">
<meta name="force-rendering" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="HandheldFriendly" content="True" >
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">
<meta content="<%=config.title%>" name="application-name">
<meta content="<%=config.title%>" name="apple-mobile-web-app-title">
<meta content="black-translucent" name="apple-mobile-web-app-status-bar-style">
<meta content="telephone=no" name="format-detection">
<link rel="preload" href="<%- theme.cdn.map.css.style %>" as="style">
<%- generate_preload_fontfamily(theme) %>
<!-- 页面元数据 -->
<%- generate_title(config, theme, page) %>
<%- generate_keywords(config, theme, page) %>
<%- open_graph(theme.open_graph) %>
<!-- feed -->
<%_ if (config.feed && config.feed.path){ _%>
<%- feed_tag(config.feed.path, {title: config.title}) %>
<%_ } _%>
<!-- import meta -->
<%_ if (config.import && config.import.meta){ _%>
<%_ (config.import.meta||[]).forEach(function(item){ _%>
<%- item %>
<%_ }) _%>
<%_ } _%>
<!-- link -->
<%_ if (config.favicon) { _%>
<link rel="shortcut icon" type='image/x-icon' href="<%- url_for(config.favicon) %>">
<%_ } _%>
<!-- import link -->
<%_ if (config.import && config.import.link){ _%>
<%_ (config.import.link||[]).forEach(function(item){ _%>
<%- item %>
<%_ }) _%>
<%_ } _%>
<style>
/* 首屏样式 */
<%- FirstCSS() %>
</style>
<%_ if (theme.plugins.tag_plugin_load_on_demand.enable) { _%>
<pjax>
<style>
/* 按需加载的标签插件样式 */
<%- TagCSS(page) %>
</style>
</pjax>
<%_ } _%>
<link rel="stylesheet" href="<%- theme.cdn.map.css.style %>" media="print" onload="this.media='all';this.onload=null">
<noscript><link rel="stylesheet" href="<%- theme.cdn.map.css.style %>"></noscript>
<%_ if (theme.plugins.darkmode.enable) { _%>
<script>
var userColorScheme=localStorage.getItem("color-scheme")
if(userColorScheme){
document.documentElement.setAttribute("color-scheme", userColorScheme);
}
</script>
<%_ } _%>
<%- partial('../_plugins/end-of-support/script') %>
<%- partial('scripts/global') %>
<!-- Custom Files head begin-->
<%- volantis_inject('head') %>
<!-- Custom Files head end-->
</head>
<header itemscope itemtype="http://schema.org/WPHeader" id="l_header" class="l_header <%- theme.navbar.visiable %> <%- theme.custom_css.navbar.effect.join(' ') %> <%- theme.pjax_cover.headerShow %>" <%- (theme.navbar.visiable == 'auto' && theme.cover.height_scheme) ? "style='opacity: 0'" : "" %> >
<div class='container'>
<div id='wrapper'>
<div class='nav-sub'>
<p class="title"></p>
<ul class='switcher nav-list-h m-phone' id="pjax-header-nav-list">
<li><a id="s-comment" class="fas fa-comments fa-fw" target="_self" href="/" onclick="return false;" title="comment"></a></li>
<% if (page.sidebar == undefined || page.sidebar != false) { %>
<li><a id="s-toc" class="s-toc fas fa-list fa-fw" target="_self" href="/" onclick="return false;" title="toc"></a></li>
<% } %>
</ul>
</div>
<div class="nav-main">
<% if (theme.navbar.logo) { %>
<% let logo = theme.navbar.logo %>
<a class="title flat-box" target="_self" href='<%- url_for("/") %>'>
<% if (logo.img) { %>
<img no-lazy class='logo' src='<%- logo.img %>'/>
<% } %>
<% if (logo.icon) { %>
<i class='<%- logo.icon %>'></i>
<% } %>
<% if (logo.title) { %>
<%- logo.title %>
<% } %>
</a>
<% } %>
<div class='menu navigation'>
<ul class='nav-list-h m-pc'>
<%
let menu_list = theme.navbar.menu;
%>
<% function menu(value, type) { %>
<% if (value.name == 'hr') { %>
<hr>
<% } else if (value.toggle == 'darkmode') { %>
<li>
<a class="menuitem flat-box header toggle-mode-btn">
<i class='<%= value.icon %> fa-fw'></i><%- value.name %>
</a>
<li>
<% } else if (value.icon && value.icon.indexOf('fa-compact-disc') > -1 && value.url == undefined && value.rows == undefined) { %>
<% if (type == 'pc') { %>
<li>
<a class="menuitem flat-box">
<i class='<%= value.icon %> fa-fw music'></i><%- value.name %>
</a>
<ul class="list-v">
<li>
<div class="aplayer-container">
<%- partial('../_plugins/aplayer/layout', {post: null, where: 'footer'}) %>
</div>
</li>
</ul>
<li>
<% } %>
<% } else if (value.name != undefined && value.url == undefined && value.rows == undefined) { %>
<li class='header'>
<% if (value.icon) { %><i class='<%= value.icon %> fa-fw'></i><% } %><%- value.name %>
</li>
<% } else { %>
<li>
<a class="menuitem flat-box faa-parent animated-hover"
<%- value.url ? `href="` + url_for(value.url) + `" title="` + (value.description || value.name) + `"`
: ` href="/" onclick="return false;" title="` + (value.description || value.name) + `"` %>
<% if (value.rel) { %>
rel="<%- value.rel %>"
<% } %>
<% if (value.target) { %>
target="<%- value.target %>"
<% } %>
<% if (value.url) { %>
active-action="action-<%= url_for(value.url).replace(/\/|%|\./g, "")?url_for(value.url).replace(/\/|%|\./g, ""):"home" %>"
<% } %>>
<% if (value.icon) { %><i class='<%= value.icon %> fa-fw'></i><% } %><%- value.name %>
</a>
<% if (value.rows) { %>
<ul class="list-v">
<% value.rows.forEach(function(value){ %>
<% menu(value, type) %>
<%})%>
</ul>
<% } %>
</li>
<% } %>
<% } %>
<% menu_list.forEach(function(value){ %>
<% menu(value, 'pc') %>
<% }) %>
</ul>
</div>
<% if (theme.search.enable) { %>
<div class="m_search">
<form name="searchform" class="form u-search-form">
<i class="icon fas fa-search fa-fw"></i>
<input type="text" class="input u-search-input" placeholder="<%- theme.navbar && theme.navbar.search %>" />
</form>
</div>
<% } %>
<ul class='switcher nav-list-h m-phone'>
<% if (theme.search.enable === true) { %>
<li><a class="s-search fas fa-search fa-fw" target="_self" href="/" onclick="return false;" title="search"></a></li>
<% } %>
<li>
<a class="s-menu fas fa-bars fa-fw" target="_self" href="/" onclick="return false;" title="menu"></a>
<ul class="menu-phone list-v navigation white-box">
<% menu_list.forEach(function(value){ %>
<% menu(value, 'mobile') %>
<% }) %>
</ul>
</li>
</ul>
<!-- Custom Files header begin -->
<%- volantis_inject('header') %>
<!-- Custom Files header end -->
</div>
</div>
</div>
</header>
<%
var topMetas = theme.article.body.top_meta || [];
if (post.top_meta == false) {
topMetas = [];
}
var bottomMetas = theme.article.body.bottom_meta || [];
if (post.bottom_meta == false) {
bottomMetas = [];
}
%>
<% if (position == 'top') { %>
<% if (post.headimg) { %>
<div class='headimg-div'>
<a class='headimg-a'>
<img itemprop="image" class='headimg' src='<%- post.headimg %>'/>
</a>
</div>
<% } else { %>
<span hidden>
<meta itemprop="image" content="<%- theme.structured_data.data.logo.path %>">
</span>
<% } %>
<div class="article-meta" id="top">
<% if (post.music && post.music.enable != false) { %>
<%- partial('../_plugins/aplayer/layout', {post: post, where: 'meta'}) %>
<% } %>
<% if (post.thumbnail && post.thumbnail.length){ %>
<a title='<%- post.title %>' href='<%- url_for(post.link || post.path) %>'>
<img itemprop="image" class='thumbnail' src='<%- post.thumbnail %>'>
</a>
<% } %>
<% if (post.title) { %>
<h1 class="title" itemprop="name headline">
<%- post.title %>
</h1>
<div class='new-meta-box'>
<% (topMetas).forEach(function(meta) { %>
<% if (meta in theme.article.body.meta_library){ %>
<%- partial('../_meta/' + meta, {post: post}) %>
<% } %>
<% }) %>
<!-- Custom Files topMeta begin-->
<%- volantis_inject('topMeta') %>
<!-- Custom Files topMeta end-->
</div>
<% } else { %>
<span hidden itemprop="name headline">
<%- post.title %>
</span>
<% } %>
</div>
<% } else if (position == 'bottom') { %>
<div class='article-meta' id="bottom">
<div class='new-meta-box'>
<% (bottomMetas).forEach(function(meta){ %>
<% if (meta in theme.article.body.meta_library) { %>
<%- partial('../_meta/' + meta, {post: post}) %>
<% } %>
<% }) %>
</div>
<!-- Custom Files bottomMeta begin -->
<%- volantis_inject('bottomMeta') %>
<!-- Custom Files bottomMeta end -->
</div>
<% } %>
<div class="post post-v3 white-box reveal <%- theme.custom_css.body.effect.join(' ') %>" itemscope itemtype="http://schema.org/Article" >
<link itemprop="mainEntityOfPage" href="<%- post.permalink %>">
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="<%- config.title %>">
</span>
<%
let showPin = false;
if (post.pin && (post.title || theme.article.preview.auto_title) && theme.article.preview.pin_icon) {
showPin = true;
}
let showTitle = false;
if (theme.article.preview.auto_title || (post.title && (post.link || post.path))) {
showTitle = true;
}
let showCat = false;
if (post.categories && post.categories.length > 0) {
showCat = true;
}
let showReadmore = false;
if (theme.article.preview.readmore == 'always' || theme.article.preview.auto_excerpt || ((post.readmore != false) && (post.excerpt || post.description || post.link))) {
showReadmore = true;
}
%>
<% if (showPin == true) { %>
<div class='pin'>
<img alt="<%- post.title %>" src='<%- theme.article.preview.pin_icon %>'/>
</div>
<% } %>
<% if (post.headimg) { %>
<div class='headimg-div'>
<a class='headimg-a' href="<%- url_for(post.link || post.path) %>">
<img itemprop="image" class='headimg' alt="<%- post.title %>" src='<%- post.headimg %>'/>
</a>
</div>
<% } else { %>
<span hidden>
<meta itemprop="image" content="<%- theme.structured_data.data.logo.path %>">
</span>
<% } %>
<% if (showTitle) { %>
<%
let pinTitle = false;
if (showPin && !post.headimg) {
pinTitle = true;
}
%>
<h2 class="article-title" <%- pinTitle ? 'pin' : '' %> itemprop="name headline">
<a href="<%- url_for(post.link || post.path) %>" itemprop="url">
<%- (post.title || post.seo_title) ? (post.title || post.seo_title) : date(post.date, theme.article.body.meta_library.date.format) %>
</a>
</h2>
<% } else { %>
<span hidden itemprop="name headline">
<%- (post.title || post.seo_title) ? (post.title || post.seo_title) : date(post.date, theme.article.body.meta_library.date.format) %>
</span>
<% } %>
<div class='md article-desc' itemprop="articleBody">
<% if (post.excerpt) { %>
<%- post.excerpt %>
<% } else if (post.description) { %>
<p><%- post.description %></p>
<% } else if (post.content) { %>
<% if (theme.article.preview.auto_excerpt) { %>
<%- truncate(strip_html(post.content), {length: 200}) %>
<% } else if(!theme.article.preview.hide_excerpt) { %>
<%- post.content %>
<% } %>
<% } %>
</div>
<% if (showCat || showReadmore || theme.article.preview.author) { %>
<div class='meta-v3' line_style='<%- theme.article.preview.line_style %>'>
<div>
<% if (theme.article.preview.author) { %>
<%
let author = theme.article.body.meta_library.author;
let aid = post.author;
if (aid && site.data && site.data.author && (aid in site.data.author)) {
author = site.data.author[aid];
}
%>
<a class='avatar' href='<%- author.url %>'><img src='<%- author.avatar %>'></a>
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="<%- author.avatar %>">
<meta itemprop="name" content="<%- author.name %>">
<meta itemprop="url" content="<%- author.url %>">
</span>
<% } %>
<time itemprop="dateCreated datePublished" datetime="<%- moment(post.date).format() %>"><%= date(post.date, config.date_format) %></time>
<!-- 关闭显示文章列表的分类 -->
<% if (false && post.categories && post.categories.length > 0) { %>
<span class="dot"></span>
<%- list_categories(post.categories, {
show_count: false,
separator: '<span class="sep"></span>',
style: 'none'
}) %>
<% for(cat of post.categories.toArray()){ %>
<span hidden itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="<%- url_for(cat.path) %>" itemprop="url"><span itemprop="name"><%- cat.name %></span></a>
</span>
<% } %>
<% } %>
</div>
<% if (showReadmore) { %>
<div>
<a class='readmore' href='<%- url_for(post.link || post.path) %>' itemprop="url">
<%- post.link ? __('post.readoriginal') : __('post.readmore') %>
</a>
</div>
<% } %>
</div>
<% } %>
</div>
<%- partial('_partial/scripts/_ctrl/cdnCtrl') _%>
<%- partial('_partial/scripts/_ctrl/coverCtrl') _%>
\ No newline at end of file
<%_
// 这里存放全局 CDN 资源控制变量 此处是硬编码
// theme.cdn.addJS("search","search/"+theme.search.service,theme.search.js) => theme.cdn.map.js.search
// theme.cdn.addCSS("first","first",theme.cdn.set.css.first) => theme.cdn.map.css.first
theme.cdnCtrl={}
if (theme.cdn.enable&&theme.cdn.prefix) {
theme.cdnCtrl.prefix=theme.cdn.prefix.replace(/\/$/g, "")
} else {
theme.cdnCtrl.prefix="https://cdn.jsdelivr.net/npm/hexo-theme-volantis@"+ theme.info.theme_version +"/source"
}
theme.cdn.map={}
theme.cdn.map.js={}
theme.cdn.map.css={}
theme.cdn.addJS=(name,source,force)=>{
if(force){
theme.cdn.map.js[name]=force
}else{
if(!source){
source=name
}
source = source.replace(/^\//g, "")
if (theme.cdn.enable) {
let suffix=theme.cdn.prefix&&theme.cdn.prefix.match(/jsdelivr/g)?'.min.js':'.js'
source= (suffix==".min.js")?source.replace(/\.min/g, ""):source
theme.cdn.map.js[name]=theme.cdnCtrl.prefix + '/js/' + source + suffix + '?time=' + Date.now()
} else {
theme.cdn.map.js[name]=url_for('/js/')+ source + '.js?time=' + Date.now()
}
}
return theme.cdn.map.js[name]
}
theme.cdn.addCSS=(name,source,force)=>{
if(force){
theme.cdn.map.css[name]=force
}else{
if(!source){
source=name
}
source = source.replace(/^\//g, "")
if (theme.cdn.enable&&theme.cdn.prefix) {
let suffix=theme.cdn.prefix.match(/jsdelivr/g)?'.min.css':'.css'
source= (suffix==".min.js")?source.replace(/\.min/g, ""):source
theme.cdn.map.css[name]=theme.cdnCtrl.prefix + '/css/' + source + suffix + '?time=' + Date.now()
} else {
theme.cdn.map.css[name]=url_for('/css/')+ source + '.css?time=' + Date.now()
}
}
return theme.cdn.map.css[name]
}
dfs = (n,path) => {
for (const key in n) {
const element = n[key];
if(element && typeof element !="string"){
dfs(element,path.concat(key))
}else{
let op=path.concat(key)
let source=""
for (let index = 1; index < op.length; index++) {
const element = op[index];
source+=element
if (index!=op.length-1) {
source+="/"
}
}
if(op[0]=="js"){
theme.cdn.addJS(op[op.length-1],source,element)
}
if(op[0]=="css"){
theme.cdn.addCSS(op[op.length-1],source,element)
}
}
}
}
// 默认配置
theme.cdn.addCSS("style")
theme.cdn.addCSS("message")
theme.cdn.addJS("app")
theme.cdn.addJS("sites","plugins/sites")
theme.cdn.addJS("friends","plugins/friends")
theme.cdn.addJS("parallax", "plugins/parallax")
theme.cdn.addJS("rightMenu", "plugins/rightMenu")
theme.cdn.addJS("contributors","plugins/contributors")
theme.cdn.addJS("message", "thirdparty/message")
theme.cdn.addJS("valine","thirdparty/valine",theme.comments.valine.js)
theme.cdn.addJS("search","search/"+theme.search.service,theme.search.js)
// 以下用于配置项 cdn.set 覆盖配置,下面是覆盖配置的方法
// cdn:
// enable: true
// # 以下配置可以覆盖 cdn.prefix,配置项的值可以为空,但是要使用CDN必须依据路径填写配置项的键
// set:
// js:
// app: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/app.js
// rightMenu: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/rightMenu.js
// parallax: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/parallax.js
// plugins:
// contributors: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/plugins/contributors.js
// friends: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/plugins/friends.js
// sites: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/js/plugins/sites.js
// css:
// style: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/css/style.css
// message: https://cdn.jsdelivr.net/gh/volantis-x/volantis-x.github.io@gh-page/css/message.css
// 更新:
// 在部署时加入了 ?time=' + Date.now()
// 使用 js(theme.cdn.map.js.app) 引入的地址会形如: /js/app.js?time=1232123123.js
// 但是无伤大雅
dfs(theme.cdn.set,[])
_%>
\ No newline at end of file
<%_
// 为保证初次进入页面流畅,要求开启pjax且浏览器禁用Javascript时(仅HTML渲染)封面控制正常
// layout/_plugins/pjax/pdata.ejs
// layout/_partial/cover.ejs
// layout/_partial/header.ejs
theme.pjax_cover={}
theme.pjax_cover.enableCover = false; // 封面是否开启
theme.pjax_cover.frontMatterCover = 'none'; // 封面控制
theme.pjax_cover.coverWrapperDisplay = 'none';
theme.pjax_cover.scrollDownDisplay = 'none';
theme.pjax_cover.headerShow = 'show';
if(theme.cover && theme.cover.height_scheme) {
theme.pjax_cover.enableCover = true;
}
if(theme.plugins.pjax.enable&&theme.plugins.pjax.cover) {
theme.pjax_cover.enableCover = true;
}
if (theme.pjax_cover.enableCover && page && page.cover) {
theme.pjax_cover.frontMatterCover = page.cover;
if (is_home() && page.prev == 0 && theme.cover.height_scheme == 'full') {
theme.pjax_cover.frontMatterCover = 'full';
} else {
theme.pjax_cover.frontMatterCover = 'half';
}
}
/*cover*/
if (theme.pjax_cover.frontMatterCover == "full") {
theme.pjax_cover.coverWrapperDisplay= "";
theme.pjax_cover.scrollDownDisplay = "";
} else if (theme.pjax_cover.frontMatterCover == "half"){
theme.pjax_cover.coverWrapperDisplay= "";
theme.pjax_cover.scrollDownDisplay = "none";
} else if (theme.pjax_cover.frontMatterCover == "none"){
theme.pjax_cover.coverWrapperDisplay= "none";
theme.pjax_cover.scrollDownDisplay = "none";
}
/*header*/
if (theme.pjax_cover.frontMatterCover == "none") {
theme.pjax_cover.headerShow="show";
} else {
theme.pjax_cover.headerShow="";
}
_%>
<script>
// https://web.dev/content-visibility/
// https://www.caniuse.com/?search=content-visibility
// https://infrequently.org/2020/12/content-visibility-scroll-fix/
// https://infrequently.org/2020/12/resize-resilient-deferred-rendering/
// 备注 目前已知的问题:
// 动态修改导致的内容高度变化(例如评论框异步渲染的外部盒子高度变化) 无法提前获知, 进而导致的首次滚动条跳动无法去除 (wontfix) 事实上不使用 content-visibility 也会有跳动, 不过是比使用 content-visibility 跳动提前
// scrollreveal 插件潜在问题 目前尚不明确
let eqIsh = (a, b, fuzz = 2) => {
return Math.abs(a - b) <= fuzz;
};
let rectNotEQ = (a, b) => {
return !eqIsh(a.width, b.width) || !eqIsh(a.height, b.height);
};
// Keep a map of elements and the dimensions of
// their place-holders, re-setting the element's
// intrinsic size when we get updated measurements
// from observers.
let spaced = new WeakMap();
// Only call this when known cheap, post layout
let reserveSpace = (el, rect = el.getClientBoundingRect()) => {
let old = spaced.get(el);
// Set intrinsic size to prevent jumping on un-painting:
// https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override
if (!old || rectNotEQ(old, rect)) {
spaced.set(el, rect);
el.style["contain-intrinsic-size"] = `${rect.width}px ${rect.height}px`;
}
};
let iObs = new IntersectionObserver(
(entries, o) => {
entries.forEach((entry) => {
// We don't care if the element is intersecting or
// has been laid out as our page structure ensures
// they'll get the right width.
reserveSpace(entry.target, entry.boundingClientRect);
});
},
{ rootMargin: "500px 0px 500px 0px" }
);
let rObs = new ResizeObserver((entries, o) => {
entries.forEach((entry) => {
reserveSpace(entry.target, entry.contentRect);
});
});
let resizeResilientDeferredRendering = (Selector) => {
let articles = document.querySelectorAll(Selector);
if (articles.length) {
articles.forEach((el) => {
iObs.observe(el);
rObs.observe(el);
});
// Workaround for Chrome bug, part 2.
//
// Re-enable browser management of rendering for the
// first article after the first paint. Double-rAF
// to ensure we get called after a layout.
requestAnimationFrame(() => {
requestAnimationFrame(() => {
articles[0].style["content-visibility"] = "auto";
});
});
}
};
let contentVisibilityScrollFix = () => {
if (!("content-visibility" in document.documentElement.style)) {
return;
}
resizeResilientDeferredRendering(".post-story");
resizeResilientDeferredRendering("article");
resizeResilientDeferredRendering(".post-wrapper");
};
contentVisibilityScrollFix();
volantis.pjax.push(contentVisibilityScrollFix);
</script>
<script>
/************这个文件存放不需要重载的全局变量和全局函数*********/
window.volantis = {}; // volantis 全局变量
volantis.dom = {}; // 页面Dom see: /source/js/app.js etc.
/******************** volantis.EventListener ********************************/
// 事件监听器 see: /source/js/app.js
volantis.EventListener = {}
// 这里存放pjax切换页面时将被移除的事件监听器
volantis.EventListener.list = []
//构造方法
function volantisEventListener(type, f, ele) {
this.type = type
this.f = f
this.ele = ele
}
// 移除事件监听器
volantis.EventListener.remove = () => {
volantis.EventListener.list.forEach(function (i) {
i.ele.removeEventListener(i.type, i.f, false)
})
volantis.EventListener.list = []
}
/******************** volantis.dom.$ ********************************/
// 注:这里没有选择器,也没有forEach一次只处理一个dom,这里重新封装主题常用的dom方法,返回的是dom对象,对象包含了以下方法,同时保留dom的原生API
function volantisDom(ele) {
if (!ele) ele = document.createElement("div")
this.ele = ele;
// ==============================================================
this.ele.find = (c) => {
let q = this.ele.querySelector(c)
if (q)
return new volantisDom(q)
}
// ==============================================================
this.ele.hasClass = (c) => {
return this.ele.className.match(new RegExp('(\\s|^)' + c + '(\\s|$)'));
}
this.ele.addClass = (c) => {
this.ele.classList.add(c);
return this.ele
}
this.ele.removeClass = (c) => {
this.ele.classList.remove(c);
return this.ele
}
this.ele.toggleClass = (c) => {
if (this.ele.hasClass(c)) {
this.ele.removeClass(c)
} else {
this.ele.addClass(c)
}
return this.ele
}
// ==============================================================
// 参数 r 为 true 表示pjax切换页面时事件监听器将被移除,false不移除
this.ele.on = (c, f, r = 1) => {
this.ele.addEventListener(c, f, false)
if (r) {
volantis.EventListener.list.push(new volantisEventListener(c, f, this.ele))
}
return this.ele
}
this.ele.click = (f, r) => {
this.ele.on("click", f, r)
return this.ele
}
this.ele.scroll = (f, r) => {
this.ele.on("scroll", f, r)
return this.ele
}
// ==============================================================
this.ele.html = (c) => {
// if(c=== undefined){
// return this.ele.innerHTML
// }else{
this.ele.innerHTML = c
return this.ele
// }
}
// ==============================================================
this.ele.hide = (c) => {
this.ele.style.display = "none"
return this.ele
}
this.ele.show = (c) => {
this.ele.style.display = "block"
return this.ele
}
// ==============================================================
return this.ele
}
volantis.dom.$ = (ele) => {
return !!ele ? new volantisDom(ele) : null;
}
/******************** RunItem ********************************/
function RunItem() {
this.list = []; // 存放回调函数
this.start = () => {
for (var i = 0; i < this.list.length; i++) {
this.list[i].run();
}
};
this.push = (fn, name, setRequestAnimationFrame = true) => {
let myfn = fn
if (setRequestAnimationFrame) {
myfn = ()=>{
volantis.requestAnimationFrame(fn)
}
}
var f = new Item(myfn, name);
this.list.push(f);
};
this.remove = (name) =>{
for (let index = 0; index < this.list.length; index++) {
const e = this.list[index];
if (e.name == name) {
this.list.splice(index,1);
}
}
}
// 构造一个可以run的对象
function Item(fn, name) {
// 函数名称
this.name = name || fn.name;
// run方法
this.run = () => {
try {
fn()
} catch (error) {
console.log(error);
}
};
}
}
/******************** Pjax ********************************/
// /layout/_plugins/pjax/index.ejs
// volantis.pjax.send(callBack[,"callBackName"]) 传入pjax:send回调函数
// volantis.pjax.push(callBack[,"callBackName"]) 传入pjax:complete回调函数
// volantis.pjax.error(callBack[,"callBackName"]) 传入pjax:error回调函数
volantis.pjax = {};
volantis.pjax.method = {
complete: new RunItem(),
error: new RunItem(),
send: new RunItem(),
};
volantis.pjax = {
...volantis.pjax,
push: volantis.pjax.method.complete.push,
error: volantis.pjax.method.error.push,
send: volantis.pjax.method.send.push,
};
/******************** Dark Mode ********************************/
// /layout/_partial/scripts/darkmode.ejs
// volantis.dark.mode 当前模式 dark or light
// volantis.dark.toggle() 暗黑模式触发器
// volantis.dark.push(callBack[,"callBackName"]) 传入触发器回调函数
volantis.dark = {};
volantis.dark.method = {
toggle: new RunItem(),
};
volantis.dark = {
...volantis.dark,
push: volantis.dark.method.toggle.push,
};
/******************** Message ********************************/
// /layout/_plugins/message/script.ejs
// volantis.message
/******************** isMobile ********************************/
// /source/js/app.js
// volantis.isMobile
// volantis.isMobileOld
/********************脚本动态加载函数********************************/
// volantis.js(src, cb) cb 可以传入onload回调函数 或者 JSON对象 例如: volantis.js("src", ()=>{}) 或 volantis.js("src", {defer:true,onload:()=>{}})
// volantis.css(src)
// 返回Promise对象,如下方法同步加载资源,这利于处理文件资源之间的依赖关系,例如:APlayer 需要在 MetingJS 之前加载
// (async () => {
// await volantis.js("...theme.plugins.aplayer.js.aplayer...")
// await volantis.js("...theme.plugins.aplayer.js.meting...")
// })();
// 已经加入了setTimeout
volantis.js = (src, cb) => {
return new Promise(resolve => {
setTimeout(function () {
var HEAD = document.getElementsByTagName("head")[0] || document.documentElement;
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
if (cb) {
if (JSON.stringify(cb)) {
for (let p in cb) {
if (p == "onload") {
script[p] = () => {
cb[p]()
resolve()
}
} else {
script[p] = cb[p]
script.onload = resolve
}
}
} else {
script.onload = () => {
cb()
resolve()
};
}
} else {
script.onload = resolve
}
script.setAttribute("src", src);
HEAD.appendChild(script);
});
});
}
volantis.css = (src) => {
return new Promise(resolve => {
setTimeout(function () {
var link = document.createElement('link');
link.rel = "stylesheet";
link.href = src;
link.onload = resolve;
document.getElementsByTagName("head")[0].appendChild(link);
});
});
}
/********************按需加载的插件********************************/
// volantis.import.jQuery().then(()=>{})
volantis.import = {
jQuery: () => {
if (typeof jQuery == "undefined") {
return volantis.js("<%- theme.plugins.jquery %>")
} else {
return new Promise(resolve => {
resolve()
});
}
}
}
/********************** requestAnimationFrame ********************************/
// 1、requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
// 2、在隐藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这当然就意味着更少的的 cpu,gpu 和内存使用量。
volantis.requestAnimationFrame = (fn)=>{
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
}
window.requestAnimationFrame(fn)
}
/************************ layoutHelper *****************************************/
volantis.layoutHelper = (helper, html, opt)=>{
opt = Object.assign({clean:false, pjax:true}, opt)
function myhelper(helper, html, clean) {
volantis.tempDiv = document.createElement("div");
volantis.tempDiv.innerHTML = html;
let layoutHelper = document.querySelector("#layoutHelper-"+helper)
if (layoutHelper) {
if (clean) {
layoutHelper.innerHTML = ""
}
layoutHelper.append(volantis.tempDiv);
}
}
myhelper(helper, html, opt.clean)
if (opt.pjax) {
volantis.pjax.push(()=>{
myhelper(helper, html, opt.clean)
},"layoutHelper-"+helper)
}
}
/****************************** 滚动事件处理 ****************************************/
volantis.scroll = {
engine: new RunItem(),
unengine: new RunItem(),
};
volantis.scroll = {
...volantis.scroll,
push: volantis.scroll.engine.push,
};
// 滚动条距离顶部的距离
volantis.scroll.getScrollTop = () =>{
let scrollPos;
if (window.pageYOffset) {
scrollPos = window.pageYOffset;
} else if (document.compatMode && document.compatMode != 'BackCompat') {
scrollPos = document.documentElement.scrollTop;
} else if (document.body) {
scrollPos = document.body.scrollTop;
}
return scrollPos;
}
// 使用 requestAnimationFrame 处理滚动事件
// `volantis.scroll.del` 中存储了一个数值, 该数值检测一定时间间隔内滚动条滚动的位移, 数值的检测频率是浏览器的刷新频率. 数值为正数时, 表示向下滚动. 数值为负数时, 表示向上滚动.
volantis.scroll.handleScrollEvents = () => {
volantis.scroll.lastScrollTop = volantis.scroll.getScrollTop()
function loop() {
const scrollTop = volantis.scroll.getScrollTop();
if (volantis.scroll.lastScrollTop !== scrollTop) {
volantis.scroll.del = scrollTop - volantis.scroll.lastScrollTop;
volantis.scroll.lastScrollTop = scrollTop;
// if (volantis.scroll.del > 0) {
// console.log("向下滚动");
// } else {
// console.log("向上滚动");
// }
volantis.scroll.engine.start();
}else{
volantis.scroll.unengine.start();
}
volantis.requestAnimationFrame(loop)
}
volantis.requestAnimationFrame(loop)
}
volantis.scroll.handleScrollEvents()
// 触发页面滚动至目标元素位置
volantis.scroll.to = (ele, option = {}) =>{
// 默认配置
opt = {
top: ele.getBoundingClientRect().top + document.documentElement.scrollTop,
behavior: "<%- theme.scroll_smooth ? 'smooth' : 'instant' %>"
}
// 定义配置
if ("top" in option) {
opt.top = option.top
}
if ("behavior" in option) {
opt.behavior = option.behavior
}
if ("addTop" in option) {
opt.top += option.addTop
}
if (!("observerDic" in option)) {
option.observerDic = 25
}
// 滚动
window.scrollTo(opt);
// 监视器
// 监视并矫正元素滚动到指定位置
// 目前用于处理 toc 部分 lazyload 引起的 cls 导致的定位失败问题
if (option.observer) {
volantis.scroll.unengine.push(()=>{
let me = ele.getBoundingClientRect().top
if(!(me >= -option.observerDic && me <= option.observerDic)){
volantis.scroll.to(ele, option)
}else{
volantis.scroll.unengine.remove("unengineObserver")
}
},"unengineObserver")
}
}
/******************************************************************************/
/******************************************************************************/
</script>
\ No newline at end of file
<% (config.import.script||[]).forEach(function(item) { %>
<%- item %>
<% }) %>
<script>
/******************** volantis.dom ********************************/
// 页面选择器 将dom对象缓存起来 see: /source/js/app.js etc.
volantis.dom.bodyAnchor = volantis.dom.$(document.getElementById("safearea")); // 页面主体
volantis.dom.topBtn = volantis.dom.$(document.getElementById('s-top')); // 向上
volantis.dom.wrapper = volantis.dom.$(document.getElementById('wrapper')); // 整个导航栏
volantis.dom.coverAnchor = volantis.dom.$(document.querySelector('#l_cover .cover-wrapper')); // 1个
volantis.dom.switcher = volantis.dom.$(document.querySelector('#l_header .switcher .s-search')); // 搜索按钮 移动端 1个
volantis.dom.header = volantis.dom.$(document.getElementById('l_header')); // 移动端导航栏
volantis.dom.search = volantis.dom.$(document.querySelector('#l_header .m_search')); // 搜索框 桌面端 移动端 1个
volantis.dom.mPhoneList = volantis.dom.$(document.querySelectorAll('#l_header .m-phone .list-v')); // 手机端 子菜单 多个
</script>
<script>
<% if (theme.plugins.fontawesome) { %>
volantis.css("<%- theme.plugins.fontawesome %>");
<% } %>
<% if (theme.plugins.fontawesome_animation.enable) { %>
volantis.css("<%- theme.plugins.fontawesome_animation.css %>");
<% } %>
<% if (theme.plugins.nodewaves.enable) { %>
volantis.css("<%- theme.plugins.nodewaves.css %>");
<% } %>
</script>
<!-- required -->
<% if (theme.plugins.globalJquery) { %>
<%- js(theme.plugins.jquery) %>
<% } %>
<!-- internal -->
<% if (theme.plugins.message && theme.plugins.message.enable) { %>
<%- partial('../../_plugins/message/script') %>
<% } %>
<% if (theme.rightmenu.enable) { %>
<%- partial('../../_plugins/rightmenu/layout') %>
<% } %>
<!-- rightmenu要在darkmode之前(ToggleButton) darkmode要在comments之前(volantis.dark.push)-->
<% if (theme.plugins.darkmode.enable) { %>
<%- partial('../../_plugins/darkmode/script') %>
<% } %>
<% if (theme.plugins.sitesjs.enable || theme.plugins.friendsjs.enable || theme.plugins.contributorsjs.enable) { %>
<%- partial('../../_plugins/github-api/script') %>
<% } %>
<% if (theme.plugins.lazyload && theme.plugins.lazyload.enable) { %>
<%- partial('../../_plugins/lazyload/script') %>
<% } %>
<% if (theme.plugins.preload.enable && theme.plugins.preload.service) { %>
<%- partial('../../_plugins/preload/script') %>
<% } %>
<% if (theme.plugins.scrollreveal.enable && theme.plugins.scrollreveal.js) { %>
<%- partial('../../_plugins/scrollreveal/script') %>
<% } %>
<% if (theme.plugins.aplayer && theme.plugins.aplayer.enable && theme.plugins.aplayer.js) { %>
<%- partial('../../_plugins/aplayer/script') %>
<% } %>
<% if (theme.comments.service && theme.comments.service.length > 0) { %>
<%- partial('../../_plugins/comments/' + theme.comments.service + '/script') %>
<% } %>
<% if (theme.analytics.busuanzi) { %>
<script defer src="<%- theme.analytics.busuanzi %>" data-pjax></script>
<% } %>
<%- js(theme.cdn.map.js.app) %>
<!-- optional -->
<% if (theme.search && theme.search.enable) { %>
<%- partial('../../_plugins/search/script') %>
<% } %>
<% if (theme.plugins.nodewaves.enable) { %>
<%- partial('../../_plugins/nodewaves/script') %>
<% } %>
<% if (theme.plugins.comment_typing.enable) { %>
<%- js(theme.plugins.comment_typing.js) %>
<% } %>
<% if (theme.plugins.code_highlight) { %>
<%- partial('../../_plugins/highlight/script') %>
<% } %>
<% if (theme.analytics && theme.analytics.leancloud && theme.analytics.leancloud.app_id) { %>
<%- partial('../../_plugins/analytics/LCCounter') %>
<% } %>
<% if (config.google_analytics_key || config.baidu_analytics_key || config.tencent_aegis_id) { %>
<%- partial('../../_plugins/analytics/script') %>
<% } %>
<% if (theme.plugins.chat_service) { %>
<%- partial('../../_plugins/chat/index') %>
<% } %>
<% if (theme.plugins.parallax.enable) { %>
<%- partial('../../_plugins/parallax/script') %>
<% } %>
<% if (theme.plugins.swiper.enable) { %>
<%- partial('../../_plugins/swiper/script') %>
<% } %>
<!-- pjax 标签必须存在于所有页面 否则 pjax error -->
<pjax>
<% if (page.plugins) { %>
<%- partial('../../_plugins/_page_plugins/index') %>
<% } %>
</pjax>
<%- partial('toc') %>
<%- partial('content-visibility-scroll-fix') %>
<% if (theme.structured_data && theme.structured_data.enable) { %>
<%- structured_data() %>
<% } %>
<!-- more -->
<% if (config.import && config.import.script) { %>
<%- partial('import') %>
<% } %>
<script>
function listennSidebarTOC() {
const navItems = document.querySelectorAll(".toc li");
if (!navItems.length) return;
const sections = [...navItems].map((element) => {
const link = element.querySelector(".toc-link");
const target = document.getElementById(
decodeURI(link.getAttribute("href")).replace("#", "")
);
// 解除 a 标签 href 的 锚点定位, a 标签 href 的 锚点定位 会随机启用?? 产生错位???
link.setAttribute("onclick","return false;")
link.setAttribute("toc-action","toc-"+decodeURI(link.getAttribute("href")).replace("#", ""))
link.setAttribute("href","/")
// 配置 点击 触发新的锚点定位
link.addEventListener("click", (event) => {
event.preventDefault();
// 这里的 addTop 是通过错位使得 toc 自动展开.
volantis.scroll.to(target,{addTop: 5, observer:false})
// Anchor id
history.pushState(null, document.title, "#" + target.id);
});
return target;
});
function activateNavByIndex(target) {
if (target.classList.contains("active-current")) return;
document.querySelectorAll(".toc .active").forEach((element) => {
element.classList.remove("active", "active-current");
});
target.classList.add("active", "active-current");
let parent = target.parentNode;
while (!parent.matches(".toc")) {
if (parent.matches("li")) parent.classList.add("active");
parent = parent.parentNode;
}
}
function findIndex(entries) {
let index = 0;
let entry = entries[index];
if (entry.boundingClientRect.top > 0) {
index = sections.indexOf(entry.target);
return index === 0 ? 0 : index - 1;
}
for (; index < entries.length; index++) {
if (entries[index].boundingClientRect.top <= 0) {
entry = entries[index];
} else {
return sections.indexOf(entry.target);
}
}
return sections.indexOf(entry.target);
}
function createIntersectionObserver(marginTop) {
marginTop = Math.floor(marginTop + 10000);
let intersectionObserver = new IntersectionObserver(
(entries, observe) => {
let scrollHeight = document.documentElement.scrollHeight;
if (scrollHeight > marginTop) {
observe.disconnect();
createIntersectionObserver(scrollHeight);
return;
}
let index = findIndex(entries);
activateNavByIndex(navItems[index]);
}, {
rootMargin: marginTop + "px 0px -100% 0px",
threshold: 0,
}
);
sections.forEach((element) => {
element && intersectionObserver.observe(element);
});
}
createIntersectionObserver(document.documentElement.scrollHeight);
}
document.addEventListener("DOMContentLoaded", ()=>{
volantis.requestAnimationFrame(listennSidebarTOC)
});
document.addEventListener("pjax:success", ()=>{
volantis.requestAnimationFrame(listennSidebarTOC)
});
</script>
\ No newline at end of file
<aside id='l_side' itemscope itemtype="http://schema.org/WPSideBar">
<%- partial('../_widget/load', {widgets: page.sidebar, where: 'sidebar'}) %>
<!-- Custom Files side begin -->
<%- volantis_inject('side') %>
<!-- Custom Files side end -->
</aside>
<script>
volantis.layoutHelper("page-plugins",`<div id="artitalk_main"></div>`,{pjax:false}) // 外层有 pjax 标签
</script>
<script>
volantis.import.jQuery().then(()=>{
volantis.js("https://cdn.jsdelivr.net/npm/artitalk").then(()=>{
new Artitalk(Object.assign(<%- JSON.stringify(theme.plugins.artitalk) %>, {}))
})
})
</script>
<style>
#artitalk_main #lazy {
background: transparent !important;
}
</style>
<script>
volantis.layoutHelper("page-plugins",`<div id="bbtalk"></div>`,{pjax:false}) // 外层有 pjax 标签
</script>
<script>
volantis.import.jQuery().then(()=>{
volantis.js("<%= theme.plugins.bbtalk.js %>").then(()=>{
bbtalk.init(Object.assign(<%- JSON.stringify(theme.plugins.bbtalk) %>, {}))
})
})
</script>
<script>
volantis.layoutHelper("page-plugins",`<div id="moments_container"></div>`,{pjax:false}) // 外层有 pjax 标签
</script>
<script>
var requests_url = '<%- theme.plugins.fcircle.api %>';
var orign_data = [];
var maxnumber = <%- theme.plugins.fcircle.max_number %>;
var addnumber = <%- theme.plugins.fcircle.add_number %>;
var opentype = '<%- theme.plugins.fcircle.opentype %>';
var nofollow = <%- theme.plugins.fcircle.nofollow %>;
var loadingCutom = '<%- theme.plugins.fcircle.loadingCutom %>'
//处理数据
if (document.getElementById('moments_container')) {
//添加加载动画
var loading_pic = document.getElementById('moments_container');
// 判断loadingCutom值是否为空
if (typeof loadingCutom == "undefined" || loadingCutom == null || loadingCutom === "") {
loading_pic.innerHTML = '<style>.loader { color: #d9dad8; font-size: 90px; text-indent: -9999em; overflow: hidden; width: 1em; height: 1em; border-radius: 50%; margin: 72px auto; position: relative; -webkit-transform: translateZ(0); -ms-transform: translateZ(0); transform: translateZ(0); -webkit-animation: load6 1.7s infinite ease, round 1.7s infinite ease; animation: load6 1.7s infinite ease, round 1.7s infinite ease; } @-webkit-keyframes load6 { 0% { box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } 5%, 95% { box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } 10%, 59% { box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em; } 20% { box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em; } 38% { box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em; } 100% { box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } } @keyframes load6 { 0% { box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } 5%, 95% { box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } 10%, 59% { box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em; } 20% { box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em; } 38% { box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em; } 100% { box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; } } @-webkit-keyframes round { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } @keyframes round { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } }</style><center><span id="moments_loading"><div class="loader"></div></span></center>';
} else {
loading_pic.innerHTML = '<center><span id="moments_loading">' + loadingCutom + '</span></center>';
}
fetch(requests_url).then(
data => data.json()
).then(
data => {
orign_data = data;
data_handle(nofollow, orign_data, maxnumber)
}
)
}
var data_handle = (nofollow, data, maxnumber) => {
var today = todaypost();
var Datetody = new Date(today);
for (var item = 0; item < data[1].length; item++) {
var Datedate = new Date(data[1][item][1]);
if (Datedate > Datetody) {
data[1].splice(item--, 1);
}
}
var today_post = 0;
var error = 0;
var unique_live_link;
var datalist = data[1].slice(0, maxnumber);
var listlenth = data[1].length;
var user_lenth = data[0].length;
var datalist_slice = slice_month(datalist);
var last_update_time = timezoon(datalist_slice);
var link_list = [];
for (var item of data[1]) {
if (item[1] === today) {
today_post += 1;
}
link_list.push(item[3]);
}
var arr = unique(link_list);
unique_live_link = arr.length;
for (var item of data[0]) {
if (item[3] === 'true') {
error += 1;
}
}
var html_item = '<h2>统计信息</h2>';
html_item += '<div id="info_user_pool" class="moments-item info_user_pool" style="">';
html_item += '<div class="moments_chart"><span class="moments_post_info_title">当前友链数:</span><span class="moments_post_info_number">' + user_lenth + ' 个</span><br><span class="moments_post_info_title">失败数:</span><span class="moments_post_info_number">' + error + ' 个</span><br></div>';
html_item += '<div class="moments_chart"><span class="moments_post_info_title">活跃友链数:</span><span class="moments_post_info_number">' + unique_live_link + ' 个</span><br><span class="moments_post_info_title">当前库存:</span><span class="moments_post_info_number">' + listlenth + ' 篇</span><br></div>';
html_item += '<div class="moments_chart"><span class="moments_post_info_title">今日更新:</span><span class="moments_post_info_number">' + today_post + ' 篇</span><br><span class="moments_post_info_title">最近更新:</span><span class="moments_post_info_number">' + last_update_time + '</span><br></div>';
html_item += '</div>';
for (var month_item of datalist_slice) {
html_item += '<h2>' + month_item[0] + '</h2>';
for (var post_item of month_item[1]) {
var rel = '';
if (nofollow && opentype == '_blank') {
rel = 'noopener nofollow';
} else if (nofollow) {
rel = 'nofollow';
} else if (opentype == '_blank') {
rel = 'noopener';
} else {
rel = '';
}
html_item += ' <div class="moments-item">';
html_item += ' <a target="' + opentype + '" class="moments-item-img" href="' + post_item[2] + '" title="' + post_item[0] + '"rel="' + rel + '">';
html_item += '<img onerror="this.onerror=null,this.src=&quot;https://cdn.jsdelivr.net/gh/Zfour/Butterfly-friend-poor-html/friendcircle/404.png&quot;"';
html_item += ' src="' + post_item[4] + '"></a>';
html_item += '<div class="moments-item-info"><div class="moments-item-time"><i class="far fa-user"></i>';
html_item += '<span>' + post_item[3] + '</span>';
html_item += ' <div class="moments_post_time"><i class="far fa-calendar-alt"></i>' +
'<time datetime="' + post_item[1] + '" title="' + post_item[1] + '">' + post_item[1] + '</time></div>';
html_item += `</div><a target="${opentype}" class="moments-item-title" href="${post_item[2]}" title="${post_item[0]}"rel="${rel}">${post_item[0]}</a></div>`;
html_item += '</div>';
}
}
if (data[1].length - maxnumber > 0) {
html_item += '<div style="text-align: center"><button type="button" class="moments_load_button" ' +
'onclick="load_more_post()">加载更多...</button>' +
'</div>'
}
html_item += '<style>.moments-item-info span{padding-left:.3rem;padding-right:.3rem}.moments_post_time time{padding-left:.3rem;cursor:default}.moments_post_info_title{font-weight:700}.moments_post_info_number{float:right}.moments_chart{align-items:flex-start;flex:1;width:100px;height:60px;margin:20px}@media screen and (max-width:500px){.info_user_pool{padding:10px;flex-direction:column;max-height:200px}.moments_chart{flex:0;width:100%;height:160px;margin:0}}.moments-item:before{border:0}@media screen and (min-width:500px){.moments_post_time{float:right}}.moments_load_button{-webkit-transition-duration:.4s;transition-duration:.4s;text-align:center;border:1px solid #ededed;border-radius:.3em;display:inline-block;background:transparent;color:#555;padding:.5em 1.25em}.moments_load_button:hover{color:#3090e4;border-color:#3090e4}.moments-item{position:relative;display:-webkit-box;display:-moz-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-moz-box-align:center;-o-box-align:center;-ms-flex-align:center;-webkit-align-items:center;align-items:center;margin:0 0 1rem .5rem;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;-ms-transition:all .2s ease-in-out;transition:all .2s ease-in-out;box-shadow:rgba(0,0,0,0.07) 0 2px 2px 0,rgba(0,0,0,0.1) 0 1px 5px 0;border-radius:2px}.moments-item-img{overflow:hidden;width:80px;height:80px}.moments-item-img img{max-width:100%;width:100%;height:100%;object-fit:cover}.moments-item-info{-webkit-box-flex:1;-moz-box-flex:1;-o-box-flex:1;box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;padding:0 .8rem}.moments-item-title{display:-webkit-box;overflow:hidden;-webkit-box-orient:vertical;font-size:1.1em;-webkit-transition:all .3s;-moz-transition:all .3s;-o-transition:all .3s;-ms-transition:all .3s;transition:all .3s;-webkit-line-clamp:1}</style>'
var moments_container = document.getElementById('moments_container');
append_div(moments_container, html_item)
};
var load_more_post = () => {
if (document.getElementById('moments_container')) {
maxnumber = maxnumber + addnumber;
document.getElementById('moments_container').innerHTML = "";
data_handle(nofollow, orign_data, maxnumber)
}
};
//加载更多文章
//将html放入指定id的div容器
var append_div = (parent, text) => {
if (document.getElementById('moments_container')) {
loading_pic.innerHTML = ``;
};
if (typeof text === 'string') {
var temp = document.createElement('div');
temp.innerHTML = text;
// 防止元素太多 进行提速
var frag = document.createDocumentFragment();
while (temp.firstChild) {
frag.appendChild(temp.firstChild);
}
parent.appendChild(frag);
} else {
parent.appendChild(text);
}
};
//去重
var unique = (arr) => {
return Array.from(new Set(arr))
};
//时区优化
var formatDate = (strDate) => {
try {
var date = new Date(Date.parse(strDate.replace(/-/g, "/")));
var gettimeoffset;
if (new Date().getTimezoneOffset()) {
gettimeoffset = new Date().getTimezoneOffset();
} else {
gettimeoffset = 8;
}
var timeoffset = gettimeoffset * 60 * 1000;
var len = date.getTime();
var date2 = new Date(len - timeoffset);
var sec = date2.getSeconds().toString();
var min = date2.getMinutes().toString();
if (sec.length === 1) {
sec = "0" + sec;
}
if (min.length === 1) {
min = "0" + min;
}
return date2.getFullYear().toString() + "/" + (date2.getMonth() + 1).toString() + "/" + date2.getDate().toString() + " " + date2.getHours().toString() + ":" + min + ":" + sec
} catch (e) {
return ""
}
};
var timezoon = (datalist_slice) => {
var time = datalist_slice[0][1][0][5];
return formatDate(time)
};
//今日时间
var todaypost = () => {
var date = new Date();
var year = date.getFullYear();
var month = (date.getMonth() + 1).toString();
var day = (date.getDate()).toString();
if (month.length === 1) {
month = "0" + month;
}
if (day.length === 1) {
day = "0" + day;
}
return year + "-" + month + "-" + day
};
//月份切片
var slice_month = (data) => {
var monthlist = [];
var datalist = [];
var data_slice = data;
for (var item in data_slice) {
data_slice[item].push(item);
if (data_slice[item][1].lenth !== 10) {
var list = data_slice[item][1].split('-');
if (list[1].length < 2) {
list[1] = "0" + list[1]
}
if (list[2].length < 2) {
list[2] = "0" + list[2]
}
data_slice[item][1] = list.join('-')
}
var month = data_slice[item][1].slice(0, 7);
if (monthlist.indexOf(month) !== -1) {
datalist[monthlist.length - 1][1].push(data_slice[item])
} else {
monthlist.push(month);
datalist.push([month, [data_slice[item]]])
}
}
for (var mounthgroup of datalist) {
mounthgroup.push(mounthgroup[1][0][6]);
}
return datalist
};
</script>
<%- partial( "../../chat/gitter/script") %>
<script>
// 这里是 page plugin
volantis.removeGitter=()=>{
document.querySelectorAll(".gitter-chat-embed").forEach(e=>{
e.remove()
})
document.querySelectorAll(".gitter-open-chat-button").forEach(e=>{
e.remove()
})
}
volantis.pjax.send(volantis.removeGitter)
</script>
\ No newline at end of file
<script>
volantis.layoutHelper("page-plugins",`<div id="hpp_talk"></div>`,{pjax:false}) // 外层有 pjax 标签
volantis.css("<%= theme.plugins.hpp.hpp_talk.css %>")
volantis.js("<%= theme.plugins.hpp.hpp_talk.js %>").then(() => {
new hpp_talk(Object.assign( <%- JSON.stringify(theme.plugins.hpp.hpp_talk) %> , {
id: "hpp_talk", //容器id
}));
})
</script>
<style>
.hpp_talk_img {
display: inline !important;
}
</style>
<style>
#post-body p {
text-indent: 2em;
}
#post-body .new-meta-box p,
#post-body .note p,
#post-body .prev-next p,
#post-body .tag p,
#post-body blockquote p,
#post-body details p,
#post-body p.p,
#post-body .tab-pane .checkbox
#post-body section p {
text-indent: initial;
}
</style>
<%_(page.plugins||[]).forEach(function(item){ _%>
<%_if (typeof item == "string") { _%>
<%- partial( item + "/index") %>
<%_}else if(typeof item == "object"){ _%>
<%- partial( Object.keys(item)[0] + "/index", { pagePlugin:item }) %>
<%_} _%>
<%_ }) _%>
<script>
// https://www.micdz.cn/article/katex-on-volantis/
if (typeof renderMathInElement == "undefined") {
volantis.css("https://cdn.jsdelivr.net/npm/katex@0.13.13/dist/katex.min.css")
function pjax_katex() {
volantis.js("https://cdn.jsdelivr.net/npm/katex@0.13.13/dist/contrib/auto-render.min.js").then(()=>{
renderMathInElement(document.body);
})
}
volantis.js("https://cdn.jsdelivr.net/npm/katex@0.13.13/dist/katex.min.js").then(pjax_katex)
volantis.pjax.push(pjax_katex)
}
</script>
\ No newline at end of file
<script>
// https://github.com/theme-next/hexo-theme-next/blob/master/layout/_third-party/math/mathjax.swig
if (typeof MathJax === 'undefined') {
window.MathJax = {
loader: {
source: {
'[tex]/amsCd': '[tex]/amscd',
'[tex]/AMScd': '[tex]/amscd'
}
},
tex: {
inlineMath: {'[+]': [['$', '$']]},
tags: 'ams'
},
options: {
renderActions: {
findScript: [10, doc => {
document.querySelectorAll('script[type^="math/tex"]').forEach(node => {
const display = !!node.type.match(/; *mode=display/);
const math = new doc.options.MathItem(node.textContent, doc.inputJax[0], display);
const text = document.createTextNode('');
node.parentNode.replaceChild(text, node);
math.start = {node: text, delim: '', n: 0};
math.end = {node: text, delim: '', n: 0};
doc.math.push(math);
});
}, '', false],
insertedScript: [200, () => {
document.querySelectorAll('mjx-container').forEach(node => {
let target = node.parentNode;
if (target.nodeName.toLowerCase() === 'li') {
target.parentNode.classList.add('has-jax');
}
});
}, '', false]
}
}
};
(function () {
var script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/mathjax@3.0/es5/tex-mml-chtml.js';
script.defer = true;
document.head.appendChild(script);
})();
} else {
// 文章章节标题不能为 “MathJax” ,否则会报错。
MathJax.startup.document.state(0);
MathJax.texReset();
MathJax.typesetPromise();
}
</script>
<% if (site.data.notification && (pagePlugin.snackbar in site.data.notification)) { %>
<% let snackbar = site.data.notification[pagePlugin.snackbar] %>
<% if (snackbar.position == 'bottom') { %>
<div id="snackbar"></div>
<script>
function Snackbar(){
document.getElementById("snackbar").innerHTML=`<div class='snackbar-wrap' theme='<%- snackbar.theme %>'>
<div class="snackbar-content">
<div class='title'><%- markdown(snackbar.title) %></div>
<div class='message'><%- markdown(snackbar.message) %></div>
<% if (snackbar.buttons && snackbar.buttons.length > 0) { %>
<div class="action">
<% snackbar.buttons.forEach((ac, i) => { %>
<% if (ac.dismiss) { %>
<a onclick="document.getElementsByClassName('snackbar-wrap')[0].style.display = 'none'">
<%- ac.title %>
</a>
<% } else { %>
<a href='<%- ac.url %>'>
<%- ac.title %>
</a>
<% } %>
<% }) %>
</div>
<% } %>
</div>
</div>`
}
</script>
<% } else if (snackbar.position == 'right') { %>
<% if (snackbar.buttons && snackbar.buttons.length > 0) { %>
<script>
function Snackbar(){
<% snackbar.buttons.forEach((ac, i) => { %>
volantis.message(
'<%- snackbar.title %>',
'<%- snackbar.message %><br>' + "<a href='<%- ac.url %>'><%- ac.title %></a>"
);
<% }) %>
}
</script>
<% } %>
<% } %>
<script>
<% if (snackbar.cache) { %>
if (!localStorage.getItem('Snackbar')) {
localStorage.setItem('Snackbar', '1');
Snackbar();
}
<% } else { %>
Snackbar()
<% }%>
</script>
<% } %>
<script defer>
const LCCounter = {
app_id: '<%= theme.analytics.leancloud.app_id %>',
app_key: '<%= theme.analytics.leancloud.app_key %>',
custom_api_server: '<%= theme.analytics.leancloud.custom_api_server %>',
// 查询存储的记录
getRecord(Counter, url, title) {
return new Promise(function (resolve, reject) {
Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify({url})))
.then(resp => resp.json())
.then(({results, code, error}) => {
if (code === 401) {
throw error;
}
if (results && results.length > 0) {
var record = results[0];
resolve(record);
} else {
Counter('post', '/classes/Counter', {url, title: title, times: 0})
.then(resp => resp.json())
.then((record, error) => {
if (error) {
throw error;
}
resolve(record);
}).catch(error => {
console.error('Failed to create', error);
reject(error);
});
}
}).catch((error) => {
console.error('LeanCloud Counter Error:', error);
reject(error);
});
})
},
// 发起自增请求
increment(Counter, incrArr) {
return new Promise(function (resolve, reject) {
Counter('post', '/batch', {
"requests": incrArr
}).then((res) => {
res = res.json();
if (res.error) {
throw res.error;
}
resolve(res);
}).catch((error) => {
console.error('Failed to save visitor count', error);
reject(error);
});
});
},
// 构建自增请求体
buildIncrement(objectId) {
return {
"method": "PUT",
"path": `/1.1/classes/Counter/${ objectId }`,
"body": {
"times": {
'__op': 'Increment',
'amount': 1
}
}
}
},
// 校验是否为有效的 UV
validUV() {
var key = 'LeanCloudUVTimestamp';
var flag = localStorage.getItem(key);
if (flag) {
// 距离标记小于 24 小时则不计为 UV
if (new Date().getTime() - parseInt(flag) <= 86400000) {
return false;
}
}
localStorage.setItem(key, new Date().getTime().toString());
return true;
},
addCount(Counter) {
var enableIncr = '<%= theme.analytics.enable %>' === 'true' && window.location.hostname !== 'localhost';
enableIncr = true;
var getterArr = [];
var incrArr = [];
// 请求 PV 并自增
var pvCtn = document.querySelector('#lc-sv');
if (pvCtn || enableIncr) {
var pvGetter = this.getRecord(Counter, '<%- config.url %>' + '/#lc-sv', 'Visits').then((record) => {
incrArr.push(this.buildIncrement(record.objectId))
var eles = document.querySelectorAll('#lc-sv #number');
if (eles.length > 0) {
eles.forEach((el,index,array)=>{
el.innerText = record.times + 1;
if (pvCtn) {
pvCtn.style.display = 'inline';
}
})
}
});
getterArr.push(pvGetter);
}
// 请求 UV 并自增
var uvCtn = document.querySelector('#lc-uv');
if (uvCtn || enableIncr) {
var uvGetter = this.getRecord(Counter, '<%- config.url %>' + '/#lc-uv', 'Visitors').then((record) => {
var vuv = this.validUV();
vuv && incrArr.push(this.buildIncrement(record.objectId))
var eles = document.querySelectorAll('#lc-uv #number');
if (eles.length > 0) {
eles.forEach((el,index,array)=>{
el.innerText = record.times + (vuv ? 1 : 0);
if (uvCtn) {
uvCtn.style.display = 'inline';
}
})
}
});
getterArr.push(uvGetter);
}
// 请求文章的浏览数,如果是当前页面就自增
var allPV = document.querySelectorAll('#lc-pv');
if (allPV.length > 0 || enableIncr) {
for (i = 0; i < allPV.length; i++) {
let pv = allPV[i];
let title = pv.getAttribute('data-title');
var url = '<%- config.url %>' + pv.getAttribute('data-path');
if (url) {
var viewGetter = this.getRecord(Counter, url, title).then((record) => {
// 是当前页面就自增
let curPath = window.location.pathname;
if (curPath.includes('index.html')) {
curPath = curPath.substring(0, curPath.lastIndexOf('index.html'));
}
if (pv.getAttribute('data-path') == curPath) {
incrArr.push(this.buildIncrement(record.objectId));
}
if (pv) {
var ele = pv.querySelector('#lc-pv #number');
if (ele) {
if (pv.getAttribute('data-path') == curPath) {
ele.innerText = (record.times || 0) + 1;
} else {
ele.innerText = record.times || 0;
}
pv.style.display = 'inline';
}
}
});
getterArr.push(viewGetter);
}
}
}
// 如果启动计数自增,批量发起自增请求
if (enableIncr) {
Promise.all(getterArr).then(() => {
incrArr.length > 0 && this.increment(Counter, incrArr);
})
}
},
fetchData(api_server) {
var Counter = (method, url, data) => {
return fetch(`${ api_server }/1.1${ url }`, {
method,
headers: {
'X-LC-Id': this.app_id,
'X-LC-Key': this.app_key,
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
};
this.addCount(Counter);
},
refreshCounter() {
var api_server = this.app_id.slice(-9) !== '-MdYXbMMI' ? this.custom_api_server : `https://${ this.app_id.slice(0, 8).toLowerCase() }.api.lncldglobal.com`;
if (api_server) {
this.fetchData(api_server);
} else {
fetch('https://app-router.leancloud.cn/2/route?appId=' + this.app_id)
.then(resp => resp.json())
.then(({api_server}) => {
this.fetchData('https://' + api_server);
});
}
}
};
LCCounter.refreshCounter();
document.addEventListener('pjax:complete', function () {
LCCounter.refreshCounter();
});
</script>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
<%- partial( theme.plugins.chat_service + "/script") %>
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册