mirror of
https://github.com/hugo-fixit/FixIt.git
synced 2026-08-30 18:22:40 +00:00
Compare commits
58 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd0b171e5f | |||
| 7ceed732d2 | |||
| e07904b0f6 | |||
| 5f5d019f09 | |||
| f4e8babd12 | |||
| 1ed0acdf35 | |||
| 3b89a4eaab | |||
| 20433ed50d | |||
| 6c83d0630c | |||
| 79b5c27ed8 | |||
| dfeaf0e9a7 | |||
| 1e493fef48 | |||
| 7f19569336 | |||
| 429698a096 | |||
| 09440190aa | |||
| 1217640d40 | |||
| 300bbe9a44 | |||
| 7ec41cdb00 | |||
| fd13ca782b | |||
| bae1678c59 | |||
| 72bd72f5ed | |||
| c09f141034 | |||
| a2d8eaa249 | |||
| ff8e5fc7bf | |||
| 84e9eea483 | |||
| 5705048952 | |||
| d379911220 | |||
| 773a8a7eb9 | |||
| 6ab33ff7bf | |||
| dc0b96210a | |||
| 4dc8d0f7d7 | |||
| 76fec05da2 | |||
| 54c773368e | |||
| 05693d8b4c | |||
| 38cf4ee0de | |||
| 3df577cb0d | |||
| 063d8fa219 | |||
| 7f38d99ae4 | |||
| c771bce957 | |||
| 2ea592b4a3 | |||
| a9fd15e47d | |||
| d6be3c1fc2 | |||
| c9af0b9018 | |||
| b2b47095eb | |||
| 002ebda06f | |||
| 551938f0b4 | |||
| 9d6ee9feef | |||
| 1bd56105b7 | |||
| b7dba0713e | |||
| dd4f422dba | |||
| aaebdfb02c | |||
| 9eb18b9e75 | |||
| 594c89eb1e | |||
| 976d1ea82a | |||
| b16a06893c | |||
| 32711ff29c | |||
| 38eb829194 | |||
| 4c9b5b6773 |
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"output": "CHANGELOG.md",
|
||||
"template": ".auto-changelog/template.hbs",
|
||||
"handlebarsSetup": ".auto-changelog/setup.js",
|
||||
"sortCommits": "relevance",
|
||||
"commitLimit": false,
|
||||
"replaceText": {
|
||||
"^(Feat|feat):": ":sparkles: Feat:",
|
||||
"^(Fix|fix):": ":bug: Fix:",
|
||||
"^(Build|build):": ":hammer: Build:",
|
||||
"^(Refactor|refactor):": ":recycle: Refactor:",
|
||||
"^(Style|style):": ":lipstick: Style:",
|
||||
"^(Perf|perf):": ":zap: Perf:",
|
||||
"^(Test|test):": ":white_check_mark: Test:",
|
||||
"^(Docs|docs):": ":memo: Docs:",
|
||||
"^(Chore|chore):": ":wrench: Chore:"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Custom Handlebars helpers
|
||||
module.exports = function (Handlebars) {
|
||||
/**
|
||||
* Handlebars helper to replace a string with another string
|
||||
* @param {String} context the string to replace
|
||||
* @param {Object} options
|
||||
* @param {String} options.hash.from the string to replace
|
||||
* @param {String} options.hash.to the string to replace with
|
||||
* @example {{replace "foo bar" from="foo" to="baz"}} => "baz bar"
|
||||
*/
|
||||
Handlebars.registerHelper('replace', function (context, options) {
|
||||
return context.replace(options.hash.from, options.hash.to)
|
||||
})
|
||||
/**
|
||||
* Handlebars helper to convert a name to a GitHub username
|
||||
* @param {String} context name to convert
|
||||
* @param {Object} options
|
||||
* @param {Boolean} [options.hash.linked=true] whether to return a linked username
|
||||
* @example {{githubUser "Cell"}} => "Lruihao"
|
||||
*/
|
||||
Handlebars.registerHelper('githubUser', function (context, { hash: { linked = false }}) {
|
||||
const map = {
|
||||
'Cell': "Lruihao",
|
||||
}
|
||||
const username = map[context] || context
|
||||
if (linked) {
|
||||
return `[@${username}](https://github.com/${username})`
|
||||
}
|
||||
return `@${username}`
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
{{!-- if need, set replaceText in config.json "#(\\d+)": "[#$1](https://github.com/hugo-fixit/FixIt/issues/$1)" --}}
|
||||
|
||||
{{#each releases}}
|
||||
{{#if href}}
|
||||
## [{{title}}]({{href}}){{#if tag}} - {{isoDate}}{{/if}}
|
||||
{{else}}
|
||||
## {{title}}{{#if tag}} - {{isoDate}}{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if summary}}
|
||||
{{summary}}
|
||||
{{/if}}
|
||||
|
||||
{{!-- List commits with `Breaking change: ` somewhere in the message --}}
|
||||
{{#commit-list commits heading='### :boom: Breaking Changes' message='^(Breaking change|BREAKING CHANGE):'}}
|
||||
- {{subject}} [`{{shorthash}}`]({{href}}) by {{githubUser author}}
|
||||
{{/commit-list}}
|
||||
|
||||
{{!-- List commits that add new features, but exclude those that have `:sparkles:` in the message --}}
|
||||
{{#commit-list commits heading='### :tada: New Features' message='(:tada:|Feat:|feat:)' exclude='^:sparkles:'}}
|
||||
- {{subject}} [`{{shorthash}}`]({{href}}) by {{githubUser author}}
|
||||
{{/commit-list}}
|
||||
|
||||
{{!-- List commits that enhance existing features, but exclude those that have `:tada:` in the message --}}
|
||||
{{#commit-list commits heading='### :sparkles: Enhancements' message='(:sparkles:|Feat:|feat:|Perf:|perf:)' exclude='^:tada:'}}
|
||||
- {{subject}} [`{{shorthash}}`]({{href}}) by {{githubUser author}}
|
||||
{{/commit-list}}
|
||||
|
||||
{{!-- List commits that bug fixes --}}
|
||||
{{#commit-list commits heading='### :bug: Bug Fixes' message='(:bug:|Fix:|fix:)'}}
|
||||
- {{subject}} [`{{shorthash}}`]({{href}}) by {{githubUser author}}
|
||||
{{/commit-list}}
|
||||
|
||||
{{!-- List commits that improve the documentation --}}
|
||||
{{#commit-list commits heading='### :memo: Documentation' message='(:memo:|Docs:|docs:)'}}
|
||||
- {{subject}} [`{{shorthash}}`]({{href}}) by {{githubUser author}}
|
||||
{{/commit-list}}
|
||||
|
||||
{{!-- List other changes commits --}}
|
||||
{{#commit-list commits heading='### :wrench: Other Changes' message='(Refactor:|refactor:|Style:|style:|Test:|test:|Chore:|chore:|Build:|build:)'}}
|
||||
- {{subject}} [`{{shorthash}}`]({{href}}) by {{githubUser author}}
|
||||
{{/commit-list}}
|
||||
|
||||
- **Full Changelog**: {{href}}
|
||||
|
||||
---
|
||||
|
||||
### Uncategorized
|
||||
|
||||
{{#if merges}}
|
||||
#### Merged pull requests
|
||||
|
||||
{{#each merges}}
|
||||
{{!-- {{#if href}}[`#{{id}}`]({{href}}){{/if}} --}}
|
||||
- {{#if commit.breaking}}**Breaking change:** {{/if}}{{message}} by {{githubUser author}} in {{#if id}}#{{id}}{{/if}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
{{#if fixes}}
|
||||
#### Closed issues
|
||||
|
||||
{{#each fixes}}
|
||||
- {{#if commit.breaking}}**Breaking change:** {{/if}}{{commit.subject}}{{#each fixes}} {{#if id}}#{{id}}{{/if}}{{/each}} by {{githubUser commit.author}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
{{/each}}
|
||||
@@ -0,0 +1 @@
|
||||
assets/lib/**/* linguist-vendored
|
||||
@@ -1,48 +0,0 @@
|
||||
name: Update Algolia Search Index
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- "docs"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
algolia-atomic:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive # Fetch Hugo themes (true OR recursive)
|
||||
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
|
||||
|
||||
- name: Setup Hugo
|
||||
uses: peaceiris/actions-hugo@v2
|
||||
with:
|
||||
hugo-version: "latest"
|
||||
extended: true
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
- name: Update Algolia Index (en)
|
||||
env:
|
||||
ALGOLIA_APP_ID: YKOM6PKLUY
|
||||
ALGOLIA_ADMIN_KEY: ${{ secrets.ALGOLIA_ADMIN_KEY }}
|
||||
ALGOLIA_INDEX_NAME: "index.en"
|
||||
ALGOLIA_INDEX_FILE: "./docs/public/index.json"
|
||||
run: |
|
||||
npm run algolia
|
||||
|
||||
- name: Update Algolia Index (zh-cn)
|
||||
env:
|
||||
ALGOLIA_APP_ID: YKOM6PKLUY
|
||||
ALGOLIA_ADMIN_KEY: ${{ secrets.ALGOLIA_ADMIN_KEY }}
|
||||
ALGOLIA_INDEX_NAME: "index.zh-cn"
|
||||
ALGOLIA_INDEX_FILE: "./docs/public/zh-cn/index.json"
|
||||
run: |
|
||||
npm run algolia
|
||||
@@ -18,4 +18,4 @@ jobs:
|
||||
hugo-version: latest
|
||||
extended: true
|
||||
- name: Build Hugo static files
|
||||
run: hugo -v --source=docs --gc --minify
|
||||
run: hugo -v --source=demo --gc --minify
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Release for new tag
|
||||
|
||||
# Controls when the action will run.
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the master branch
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
# This workflow contains a single job called "build"
|
||||
build:
|
||||
# The type of runner that the job will run on
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Fetch all history for generating release notes
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Install dependencies and generate release notes
|
||||
run: |
|
||||
npm install
|
||||
npm run release -- --starting-version ${{ github.ref_name }}
|
||||
|
||||
- name: GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
# Creates a draft release. Defaults to false
|
||||
draft: true
|
||||
body_path: CHANGELOG.md
|
||||
+1
-1
@@ -25,4 +25,4 @@ $RECYCLE.BIN/
|
||||
## Linux
|
||||
.directory
|
||||
|
||||
|
||||
CHANGELOG.md
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "docs"]
|
||||
path = docs
|
||||
url = https://github.com/hugo-fixit/docs.git
|
||||
+7
-1
@@ -7,7 +7,7 @@ First, fork this repository by clicking the fork button.
|
||||
Next, clone your forked repo.
|
||||
|
||||
```bash
|
||||
git clone --recursive https://github.com/hugo-fixit/FixIt.git && cd FixIt
|
||||
git clone https://github.com/hugo-fixit/FixIt.git && cd FixIt
|
||||
```
|
||||
|
||||
Then, install the dev dependencies.
|
||||
@@ -27,6 +27,12 @@ npm run server
|
||||
npm run server:production
|
||||
```
|
||||
|
||||
If you want to do docs-related theme changes, the simplest way is to have both `FixIt` and `fixit-docs` cloned as sibling directories, and then run:
|
||||
|
||||
```bash
|
||||
npm run server:docs
|
||||
```
|
||||
|
||||
Finally, create a new pull request at <https://github.com/hugo-fixit/FixIt/pulls> to submit your contribution 🎉
|
||||
|
||||
## Git standard for developers
|
||||
|
||||
@@ -2,7 +2,7 @@ The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 LIUZHICHAO.COM
|
||||
Copyright (c) 2019-2020 DILLONZQ.COM
|
||||
Copyright (c) 2021-2023 LRUIHAO.CN
|
||||
Copyright (c) 2021-2024 Lruihao (https://lruihao.cn)
|
||||
|
||||
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
|
||||
|
||||
@@ -6,65 +6,27 @@
|
||||
|
||||
👉 English README | [简体中文说明](README.zh-cn.md)
|
||||
|
||||
> [FixIt](https://github.com/hugo-fixit/FixIt) is a **clean**, **elegant** but **advanced** blog theme for [Hugo](https://gohugo.io/).
|
||||
[FixIt](https://github.com/hugo-fixit/FixIt) is a **clean**, **elegant** but **advanced** blog theme for [Hugo](https://gohugo.io/).
|
||||
|
||||
It is based on the original [LoveIt Theme](https://github.com/dillonzq/LoveIt), [KeepIt Theme](https://github.com/Fastbyte01/KeepIt) and [LeaveIt Theme](https://github.com/liuzc/LeaveIt).
|
||||
It is based on the original [LoveIt Theme](https://github.com/dillonzq/LoveIt), [KeepIt Theme](https://github.com/Fastbyte01/KeepIt) and [LeaveIt Theme](https://github.com/liuzc/LeaveIt).[^1]
|
||||
|
||||
The FixIt theme inherits the excellent features of these themes, and adds new features and optimizations on those basis. Please read [Why Choose FixIt](#why-choose-fixit) to learn more.
|
||||
|
||||

|
||||

|
||||
|
||||
## Getting started
|
||||
|
||||
Head to the [getting started page](http://fixit.lruihao.cn/documentation/getting-started/) or start with a template:
|
||||
- [Installation](https://fixit.lruihao.cn/documentation/installation/)
|
||||
- [Getting Started](https://fixit.lruihao.cn/documentation/getting-started/)
|
||||
- [Content Management](https://fixit.lruihao.cn/documentation/content-management/)
|
||||
- [Advanced Usage](https://fixit.lruihao.cn/documentation/advanced/)
|
||||
|
||||
- [hugo-fixit/hugo-fixit-blog-git](https://github.com/hugo-fixit/hugo-fixit-blog-git)
|
||||
- [hugo-fixit/hugo-fixit-blog-go](https://github.com/hugo-fixit/hugo-fixit-blog-go)
|
||||
Alternatively, you can run the [documentation site](https://fixit.lruihao.cn/) locally. For more details, see [hugo-fixit/docs](https://github.com/hugo-fixit/docs).
|
||||
|
||||
## [Documentation](https://fixit.lruihao.cn/categories/documentation/)
|
||||
## Template repository
|
||||
|
||||
Head to this [documentation page](https://fixit.lruihao.cn/documentation/basics/) for a complete guidence to get started with the FixIt theme.
|
||||
|
||||
Or run [Documentation Site](https://fixit.lruihao.cn) locally, see more details from [Contributing](#contributing).
|
||||
|
||||
In addition, there is the [FixIt wiki](https://github.com/hugo-fixit/FixIt/wiki).
|
||||
|
||||
## Migrate from LoveIt
|
||||
|
||||
If you are currently using the LoveIt theme (or some other themes), it is very easy to migrate to FixIt.
|
||||
|
||||
You can add this repo as a submodule of your site directory. Alternatively, you can install the theme in [other ways](https://fixit.lruihao.cn/documentation/basics/#install-theme).
|
||||
|
||||
```bash
|
||||
git submodule add https://github.com/hugo-fixit/FixIt.git themes/FixIt
|
||||
```
|
||||
|
||||
And later you can update the submodule in your site directory to the latest commit using this command:
|
||||
|
||||
```bash
|
||||
git submodule update --remote --merge
|
||||
```
|
||||
|
||||
Next, go to the `hugo.toml` and change the default theme to `FixIt`.
|
||||
|
||||
```diff
|
||||
- theme = "LoveIt"
|
||||
+ theme = "FixIt"
|
||||
```
|
||||
|
||||
Now the migration is finished and everything is ready 🎉
|
||||
|
||||
## Why choose FixIt
|
||||
|
||||
The FixIt theme inherits the excellent features of themes such as LoveIt, and adds new features and optimizations on those basis, as detailed in [Features](#features). In addition, the FixIt theme has the following advantages:
|
||||
|
||||
- Complete Chinese and English official documentations
|
||||
- Community support: Theme official website, Discussions and official QQ group
|
||||
- Continuously and actively update
|
||||
- Constantly incorporate suggestions and ideas from all sides
|
||||
- Highly open theme customizable section
|
||||
|
||||
In short, if you prefer the design language and freedom of the FixIt theme, and if you like to personalize your own themes as I do, the FixIt theme may be more suitable for you.
|
||||
- [hugo-fixit/hugo-fixit-start](https://github.com/hugo-fixit/hugo-fixit-start)
|
||||
- [hugo-fixit/hugo-fixit-start1](https://github.com/hugo-fixit/hugo-fixit-start1)
|
||||
- [hugo-fixit/docs](https://github.com/hugo-fixit/docs)
|
||||
- [Lruihao/hugo-blog](https://github.com/Lruihao/hugo-blog)
|
||||
|
||||
## Who used FixIt
|
||||
|
||||
@@ -180,7 +142,7 @@ Make sure that you follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) while contrib
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
<details open>
|
||||
<details>
|
||||
<summary>Thanks to the authors of following resources included in the theme:</summary>
|
||||
|
||||
- [normalize.css](https://github.com/necolas/normalize.css)
|
||||
@@ -220,7 +182,7 @@ Make sure that you follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) while contrib
|
||||
|
||||
</details>
|
||||
|
||||
<details open>
|
||||
<details>
|
||||
<summary>The FixIt also draws on some features of the following projects, and thanks to their authors as well:</summary>
|
||||
|
||||
- [DoIt](https://github.com/HEIGE-PCloud/DoIt)
|
||||
@@ -234,15 +196,18 @@ FixIt is licensed under the **MIT** license. Check the [LICENSE file](LICENSE) f
|
||||
|
||||
## Author
|
||||
|
||||
[Lruihao](https://github.com/Lruihao "Follow me on GitHub")
|
||||
Follow [Lruihao](https://github.com/Lruihao "Follow me on GitHub")
|
||||
|
||||
## Sponsor
|
||||
|
||||
Giving me a Star 🌟 is already the greatest encouragement and support for me.\
|
||||
If you enjoy the theme, please consider buying me a coffee ☕️.
|
||||
[](https://github.com/hugo-fixit/FixIt)
|
||||
|
||||
If you enjoy the theme, please consider buying me a coffee ☕️. Thanks!
|
||||
|
||||
- [PayPal](https://paypal.me/Lruihao)
|
||||
- [Alipay](images/alipay.jpg)
|
||||
- [Wechat](images/wechatpay.jpg)
|
||||
|
||||
Thanks! ❤️
|
||||
Don't forget to leave a ⭐️ if you like this theme, thanks!
|
||||
|
||||
[^1]: The theme name is interesting: "leave it, keep it, love it, fix it". Appears and leaves, loves but cannot keep. Doesn't it look like that damn love and BUG? 🤣
|
||||
|
||||
+25
-60
@@ -6,65 +6,27 @@
|
||||
|
||||
👉 [English README](README.md) | 简体中文说明
|
||||
|
||||
> [FixIt](https://github.com/hugo-fixit/FixIt) 是一个**简洁**、**优雅**且**高效**的 [Hugo](https://gohugo.io/) 博客主题。
|
||||
[FixIt](https://github.com/hugo-fixit/FixIt) 是一个**简洁**、**优雅**且**高效**的 [Hugo](https://gohugo.io/) 博客主题。[]
|
||||
|
||||
它的原型基于 [LoveIt 主题](https://github.com/dillonzq/LoveIt),[KeepIt 主题](https://github.com/Fastbyte01/KeepIt) 和 [LeaveIt 主题](https://github.com/liuzc/LeaveIt)。
|
||||
它的原型基于 [LoveIt 主题](https://github.com/dillonzq/LoveIt),[KeepIt 主题](https://github.com/Fastbyte01/KeepIt) 和 [LeaveIt 主题](https://github.com/liuzc/LeaveIt)。[^1]
|
||||
|
||||
FixIt 主题继承了这些主题的优秀功能,并在此基础上添加了新的功能与优化,请阅读 [为什么选择 FixIt](#为什么选择-FixIt) 来了解更多。
|
||||

|
||||
|
||||

|
||||
## 主题文档
|
||||
|
||||
## 快速上手
|
||||
- [安装篇](https://fixit.lruihao.cn/zh-cn/documentation/installation/)
|
||||
- [入门篇](https://fixit.lruihao.cn/zh-cn/documentation/getting-started/)
|
||||
- [内容管理](https://fixit.lruihao.cn/zh-cn/documentation/content-management/)
|
||||
- [进阶篇](https://fixit.lruihao.cn/zh-cn/documentation/advanced/)
|
||||
|
||||
前往 [快速上手页面](https://fixit.lruihao.cn/zh-cn/documentation/getting-started/) 或从一个模板直接开始:
|
||||
或者在本地运行 [文档站点](https://fixit.lruihao.cn/zh-cn/),更多细节详见 [hugo-fixit/docs](https://github.com/hugo-fixit/docs)。
|
||||
|
||||
- [hugo-fixit/hugo-fixit-blog-git](https://github.com/hugo-fixit/hugo-fixit-blog-git)
|
||||
- [hugo-fixit/hugo-fixit-blog-go](https://github.com/hugo-fixit/hugo-fixit-blog-go)
|
||||
## 模板仓库
|
||||
|
||||
## [完整文档](https://fixit.lruihao.cn/zh-cn/categories/documentation/)
|
||||
|
||||
前往这篇 [文档](https://fixit.lruihao.cn/zh-cn/documentation/basics/),阅读关于安装与使用的详细指南。
|
||||
|
||||
或者在本地运行 [文档站点](https://fixit.lruihao.cn/zh-cn/),更多细节详见 [参与贡献](#参与贡献)。
|
||||
|
||||
除此之外,还有 [FixIt 主题维基](https://github.com/hugo-fixit/FixIt/wiki)。
|
||||
|
||||
## 从 LoveIt 迁移
|
||||
|
||||
如果你现在正在使用 LoveIt 主题(或者一些其他的主题),你可以很容易地迁移至 FixIt。
|
||||
|
||||
你可以将这个主题仓库添加为你的网站目录的子模块。或者,你可以通过 [其他方式](https://fixit.lruihao.cn/zh-cn/documentation/basics/#install-theme) 安装主题。
|
||||
|
||||
```bash
|
||||
git submodule add https://github.com/hugo-fixit/FixIt.git themes/FixIt
|
||||
```
|
||||
|
||||
之后,你可以在站点目录通过这条命令来将主题更新至最新版本:
|
||||
|
||||
```bash
|
||||
git submodule update --remote --merge
|
||||
```
|
||||
|
||||
接着,前往 `hugo.toml` 并将默认主题更改为 `FixIt`。
|
||||
|
||||
```diff
|
||||
- theme = "LoveIt"
|
||||
+ theme = "FixIt"
|
||||
```
|
||||
|
||||
这样就完成了迁移工作,现在一切准备就绪 🎉
|
||||
|
||||
## 为什么选择 FixIt
|
||||
|
||||
FixIt 主题继承了 LoveIt 等主题的优秀功能,并在它们的基础上添加了新的功能与优化,详见 [特性](#特性)。除此之外,FixIt 主题还有以下优点:
|
||||
|
||||
- 完善的中英文官方文档
|
||||
- 社区支持:主题官网、Discussions 和官方 QQ 群
|
||||
- 持续积极地更新
|
||||
- 不断收纳各方的建议和想法
|
||||
- 高度开放主题可自定义部分
|
||||
|
||||
总之,如果你更偏好 FixIt 主题的设计语言和自由度,如果你和我一样喜欢个性化自定义主题,那么,FixIt 主题可能是更适合你。
|
||||
- [hugo-fixit/hugo-fixit-start](https://github.com/hugo-fixit/hugo-fixit-start)
|
||||
- [hugo-fixit/hugo-fixit-start1](https://github.com/hugo-fixit/hugo-fixit-start1)
|
||||
- [hugo-fixit/docs](https://github.com/hugo-fixit/docs)
|
||||
- [Lruihao/hugo-blog](https://github.com/Lruihao/hugo-blog)
|
||||
|
||||
## 谁在用 FixIt
|
||||
|
||||
@@ -166,7 +128,7 @@ FixIt 支持下列语言:
|
||||
|
||||
## 问题、想法、bugs 和 PRs
|
||||
|
||||
所有的反馈都是欢迎的!详见 [议题](https://github.com/hugo-fixit/FixIt/issues) 或者 [讨论](https://github.com/hugo-fixit/FixIt/discussions)。
|
||||
所有的反馈都是欢迎的!详见 [议题](https://github.com/hugo-fixit/FixIt/issues) 或者 [讨论](https://github.com/hugo-fixit/FixIt/discussions) 或者加入 QQ 群:`814031017`。
|
||||
|
||||
## 参与贡献
|
||||
|
||||
@@ -184,7 +146,7 @@ FixIt 支持下列语言:
|
||||
|
||||
## 致谢
|
||||
|
||||
<details open>
|
||||
<details>
|
||||
<summary>FixIt 主题中用到了以下项目,感谢它们的作者:</summary>
|
||||
|
||||
- [normalize.css](https://github.com/necolas/normalize.css)
|
||||
@@ -224,7 +186,7 @@ FixIt 支持下列语言:
|
||||
|
||||
</details>
|
||||
|
||||
<details open>
|
||||
<details>
|
||||
<summary>FixIt 主题还借鉴了以下项目的部分功能,同样感谢它们的作者:</summary>
|
||||
|
||||
- [DoIt](https://github.com/HEIGE-PCloud/DoIt)
|
||||
@@ -234,19 +196,22 @@ FixIt 支持下列语言:
|
||||
|
||||
## 许可协议
|
||||
|
||||
FixIt 根据 **MIT** 许可协议授权。 更多信息请查看 [LICENSE 文件](LICENSE)。
|
||||
FixIt 根据 **MIT** 许可协议授权。更多信息请查看 [LICENSE 文件](LICENSE)。
|
||||
|
||||
## 作者
|
||||
|
||||
[Lruihao](https://github.com/Lruihao "在 GitHub 上关注我")
|
||||
Follow [Lruihao](https://github.com/Lruihao "在 GitHub 上关注我")
|
||||
|
||||
## 赞助支持
|
||||
|
||||
给我一个 Star 🌟 已经是对我最大的鼓励和支持了。\
|
||||
如果你喜爱这个主题,请考虑给我买杯咖啡 ☕️。
|
||||
[](https://github.com/hugo-fixit/FixIt)
|
||||
|
||||
如果你喜爱这个主题,请考虑给我买杯咖啡 ☕️,谢谢!
|
||||
|
||||
- [PayPal](https://paypal.me/Lruihao)
|
||||
- [支付宝](images/alipay.jpg)
|
||||
- [微信支付](images/wechatpay.jpg)
|
||||
|
||||
谢谢!❤️
|
||||
如果你喜欢这个主题,别忘了留下一颗 ⭐️ 哦,谢谢!
|
||||
|
||||
[^1]: 主题名称趣谈:“leave it, keep it,love it,fix it”。出现又离开,爱而不得。这像不像那该死的爱情和 BUG 呢?🤣
|
||||
|
||||
@@ -97,7 +97,8 @@
|
||||
|
||||
.featured-image-preview {
|
||||
width: 100%;
|
||||
padding: 30% 0 0;
|
||||
// use the same proportions as the cover image of https://dev.to/
|
||||
aspect-ratio: auto 1000 / 420;
|
||||
position: relative;
|
||||
margin: 0.6rem auto;
|
||||
@include transition(transform 0.4s ease);
|
||||
|
||||
@@ -203,10 +203,10 @@
|
||||
|
||||
dl {
|
||||
dt {
|
||||
margin-bottom: 0.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
dd {
|
||||
margin-inline-start: 1.25em;
|
||||
margin: 0.25em 0 1em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ code {
|
||||
}
|
||||
|
||||
// indented code
|
||||
pre {
|
||||
pre:not(.mermaid[data-processed='true']) {
|
||||
margin: 0;
|
||||
line-height: 1.45em;
|
||||
padding: 0.5rem;
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
>#comments {
|
||||
padding: 2rem 0;
|
||||
@extend .print-d-none;
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,8 @@
|
||||
text-align: center;
|
||||
margin-top: 3rem;
|
||||
|
||||
.fixit-encryptor-shortcode & {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
#fixit-decryptor-input,
|
||||
.fixit-decryptor-input,
|
||||
.fixit-decryptor-btn,
|
||||
.fixit-encryptor-btn {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
@@ -40,9 +36,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
#fixit-decryptor-input,
|
||||
.fixit-decryptor-input {
|
||||
width: clamp(50%, 400px, 100%);
|
||||
width: calc(clamp(50%, 450px, 100%) - 100px);
|
||||
height: 3rem;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
@@ -53,10 +48,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.fixit-decryptor-btn,
|
||||
.fixit-encryptor-btn {
|
||||
cursor: pointer;
|
||||
@include transition(all 0.1s ease-out);
|
||||
padding: 0.6rem 1rem;
|
||||
padding: 0.8rem 1rem;
|
||||
|
||||
background-color: $header-background-color;
|
||||
|
||||
@@ -66,6 +62,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
.encrypted-hidden {
|
||||
display: none;
|
||||
// fixit-encryptor shortcodes
|
||||
fixit-encryptor {
|
||||
.fixit-decryptor-container {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
&.decrypted > .fixit-decryptor-container {
|
||||
.fixit-decryptor-loading,
|
||||
.fixit-decryptor-input,
|
||||
.fixit-decryptor-btn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.encrypted-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
.mermaid {
|
||||
text-align: center;
|
||||
&[data-processed='true'] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
svg {
|
||||
max-width: 100%;
|
||||
|
||||
@@ -13,9 +13,9 @@ libFiles:
|
||||
# aplayer@1.10.1 https://github.com/MoePlayer/APlayer
|
||||
aplayerCSS: aplayer@1.10.1/dist/APlayer.min.css
|
||||
aplayerJS: aplayer@1.10.1/dist/APlayer.min.js
|
||||
# artalk@2.6.4 https://github.com/ArtalkJS/Artalk
|
||||
artalkCSS: artalk@2.6.4/dist/Artalk.css
|
||||
artalkJS: artalk@2.6.4/dist/Artalk.js
|
||||
# artalk@latest https://github.com/ArtalkJS/Artalk
|
||||
artalkCSS: artalk@latest/dist/Artalk.css
|
||||
artalkJS: artalk@latest/dist/Artalk.js
|
||||
# autocomplete-js@0.38.1 https://github.com/algolia/autocomplete
|
||||
# TODO update autocompleteJS: '@algolia/autocomplete-js@1.7.1/dist/umd/index.production.js'
|
||||
autocompleteJS: autocomplete.js@0.38.1/dist/autocomplete.min.js
|
||||
@@ -57,9 +57,6 @@ libFiles:
|
||||
# TODO update to 3.x
|
||||
mapboxGLCSS: mapbox-gl@2.10.0/dist/mapbox-gl.css
|
||||
mapboxGLJS: mapbox-gl@2.10.0/dist/mapbox-gl.js
|
||||
# mermaid@9.4.3 https://github.com/mermaid-js/mermaid
|
||||
# TODO bump Mermaid from 9.x to 10.x
|
||||
mermaidJS: mermaid@9.4.3/dist/mermaid.min.js
|
||||
# meting@2.0.1 https://github.com/metowolf/MetingJS
|
||||
metingJS: meting@2.0.1/dist/Meting.min.js
|
||||
# object-fit-images@3.2.4 https://github.com/fregante/object-fit-images
|
||||
|
||||
@@ -13,9 +13,9 @@ libFiles:
|
||||
# aplayer@1.10.1 https://github.com/MoePlayer/APlayer
|
||||
aplayerCSS: aplayer@1.10.1/dist/APlayer.min.css
|
||||
aplayerJS: aplayer@1.10.1/dist/APlayer.min.js
|
||||
# artalk@2.6.4 https://github.com/ArtalkJS/Artalk
|
||||
artalkCSS: artalk@2.6.4/dist/Artalk.css
|
||||
artalkJS: artalk@2.6.4/dist/Artalk.js
|
||||
# artalk@latest https://github.com/ArtalkJS/Artalk
|
||||
artalkCSS: artalk@latest/dist/Artalk.css
|
||||
artalkJS: artalk@latest/dist/Artalk.js
|
||||
# autocomplete-js@0.38.1 https://github.com/algolia/autocomplete
|
||||
# TODO update autocompleteJS: '@algolia/autocomplete-js@1.7.1/dist/umd/index.production.js'
|
||||
autocompleteJS: autocomplete.js@0.38.1/dist/autocomplete.min.js
|
||||
@@ -57,9 +57,6 @@ libFiles:
|
||||
# TODO update to 3.x
|
||||
mapboxGLCSS: mapbox-gl@2.10.0/dist/mapbox-gl.css
|
||||
mapboxGLJS: mapbox-gl@2.10.0/dist/mapbox-gl.js
|
||||
# mermaid@9.4.3 https://github.com/mermaid-js/mermaid
|
||||
# TODO bump Mermaid from 9.x to 10.x
|
||||
mermaidJS: mermaid@9.4.3/dist/mermaid.min.js
|
||||
# meting@2.0.1 https://github.com/metowolf/MetingJS
|
||||
metingJS: meting@2.0.1/dist/Meting.min.js
|
||||
# object-fit-images@3.2.4 https://github.com/fregante/object-fit-images
|
||||
|
||||
+18
-18
@@ -1,35 +1,35 @@
|
||||
/**
|
||||
* Custom javascript for FixIt site.
|
||||
* Custom JavaScript for FixIt blog site.
|
||||
* @author @Lruihao https://lruihao.cn
|
||||
*/
|
||||
const FixItCustom = new (function () {
|
||||
class FixItBlog {
|
||||
/**
|
||||
* Hello World
|
||||
* You can define your own functions below.
|
||||
* @returns {FixItCustom}
|
||||
* say hello
|
||||
* you can define your own functions below
|
||||
* @returns {FixItBlog}
|
||||
*/
|
||||
this.hello = () => {
|
||||
console.log('FixItCustom echo: Hello FixIt!');
|
||||
hello() {
|
||||
console.log('custom.js: Hello FixIt!');
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
* @returns {FixItCustom}
|
||||
* initialize
|
||||
* @returns {FixItBlog}
|
||||
*/
|
||||
this.init = () => {
|
||||
// Custom infos.
|
||||
init() {
|
||||
this.hello();
|
||||
return this;
|
||||
};
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediate.
|
||||
* immediate execution
|
||||
*/
|
||||
(() => {
|
||||
FixItCustom.init();
|
||||
// It will be executed when the DOM tree is built.
|
||||
window.fixitBlog = new FixItBlog();
|
||||
// it will be executed when the DOM tree is built
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// FixItCustom.init();
|
||||
window.fixitBlog.init();
|
||||
});
|
||||
})();
|
||||
|
||||
+110
-83
@@ -12,86 +12,125 @@ FixItDecryptor = function (options = {}) {
|
||||
this.options = options || {};
|
||||
this.options.duration = this.options.duration || 24 * 60 * 60; // default cache one day
|
||||
this.decryptedEventSet = new Set();
|
||||
this.partialDecryptedEventSet = new Set();
|
||||
this.resetEventSet = new Set();
|
||||
this.$el = document.querySelector('.fixit-decryptor-container');
|
||||
|
||||
/**
|
||||
* decrypt content
|
||||
* @param {String} base64EncodeContent encrypted content
|
||||
* @param {Element} $content content element
|
||||
* @param {String} salt salt string
|
||||
* @param {Boolean} [isAll=true] whether to decrypt all content
|
||||
*/
|
||||
var _decryptContent = (base64EncodeContent) => {
|
||||
var _decryptContent = ($content, salt, isAll=true) => {
|
||||
try {
|
||||
this.$el.querySelector('.fixit-decryptor-loading').classList.add('d-none');
|
||||
this.$el.querySelector('#fixit-decryptor-input').classList.add('d-none');
|
||||
this.$el.querySelector('.fixit-encryptor-btn').classList.remove('d-none');
|
||||
document.querySelector('#content').insertAdjacentHTML(
|
||||
if (isAll) {
|
||||
// decrypt all content
|
||||
this.$el.querySelector('.fixit-decryptor-loading').classList.add('d-none');
|
||||
this.$el.querySelector('.fixit-decryptor-input').classList.add('d-none');
|
||||
this.$el.querySelector('.fixit-decryptor-btn').classList.add('d-none');
|
||||
this.$el.querySelector('.fixit-encryptor-btn').classList.remove('d-none');
|
||||
} else {
|
||||
// decrypt shortcode content
|
||||
$content.parentElement.classList.add('decrypted');
|
||||
}
|
||||
$content.insertAdjacentHTML(
|
||||
'afterbegin',
|
||||
CryptoJS.enc.Base64.parse(base64EncodeContent).toString(CryptoJS.enc.Utf8)
|
||||
CryptoJS.enc.Base64
|
||||
.parse($content.getAttribute('data-content').replace(salt, ''))
|
||||
.toString(CryptoJS.enc.Utf8)
|
||||
);
|
||||
} catch (err) {
|
||||
return console.error(err);
|
||||
}
|
||||
// decrypted hook
|
||||
console.log(this.decryptedEventSet)
|
||||
for (const event of this.decryptedEventSet) {
|
||||
event();
|
||||
}
|
||||
const eventSet = isAll ? this.decryptedEventSet : this.partialDecryptedEventSet;
|
||||
for (const event of eventSet) {
|
||||
event($content);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* validate password
|
||||
* @param {Element} $decryptor decryptor element
|
||||
* @param {Element} $content content element
|
||||
* @param {Function} callback callback function after password validation
|
||||
* @returns
|
||||
*/
|
||||
var _validatePassword = ($decryptor, $content, callback) => {
|
||||
const password = $content.getAttribute('data-password');
|
||||
const inputEl = $decryptor.querySelector('.fixit-decryptor-input');
|
||||
const input = inputEl.value.trim();
|
||||
const inputMd5 = CryptoJS.MD5(input).toString();
|
||||
const inputSha256 = CryptoJS.SHA256(input).toString();
|
||||
const saltLen = input.length % 2 ? input.length : input.length + 1;
|
||||
|
||||
inputEl.value = '';
|
||||
inputEl.blur();
|
||||
if (!input) {
|
||||
alert('Please enter the correct password!');
|
||||
return console.warn('Please enter the correct password!');
|
||||
}
|
||||
if (inputMd5 !== password) {
|
||||
alert(`Password error: ${input} not the correct password!`);
|
||||
return console.warn(`Password error: ${input} not the correct password!`);
|
||||
}
|
||||
callback(inputMd5, inputSha256.slice(saltLen));
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize FixIt decryptor
|
||||
*/
|
||||
_proto.init = () => {
|
||||
this.addEventListener('decrypted', this.options?.decrypted);
|
||||
this.addEventListener('partial-decrypted', this.options?.partialDecrypted);
|
||||
this.addEventListener('reset', this.options?.reset);
|
||||
this.validateCache();
|
||||
|
||||
const _decryptor = this;
|
||||
this.$el.querySelector('#fixit-decryptor-input')?.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
const $content = document.querySelector('#content');
|
||||
const password = $content.getAttribute('data-password');
|
||||
const input = this.value.trim();
|
||||
const saltLen = input.length % 2 ? input.length : input.length + 1;
|
||||
const inputMd5 = CryptoJS.MD5(input).toString();
|
||||
const inputSha256 = CryptoJS.SHA256(input).toString();
|
||||
|
||||
this.value = '';
|
||||
this.blur();
|
||||
if (!input) {
|
||||
alert('Please enter the correct password!');
|
||||
return console.warn('Please enter the correct password!');
|
||||
}
|
||||
if (inputMd5 !== password) {
|
||||
alert(`Password error: ${input} not the correct password!`);
|
||||
return console.warn(`Password error: ${input} not the correct password!`);
|
||||
}
|
||||
const decryptorHandler = () => {
|
||||
const $content = document.querySelector('#content');
|
||||
_validatePassword(this.$el, $content, (password, salt) => {
|
||||
// cache decryption statistics
|
||||
window.localStorage?.setItem(
|
||||
`fixit-decryptor/#${location.pathname}`,
|
||||
JSON.stringify({
|
||||
expiration: Math.ceil(Date.now() / 1000) + _decryptor.options.duration,
|
||||
md5: inputMd5,
|
||||
sha256: inputSha256.slice(saltLen)
|
||||
expiration: Math.ceil(Date.now() / 1000) + this.options.duration,
|
||||
password,
|
||||
salt,
|
||||
})
|
||||
);
|
||||
_decryptContent($content.getAttribute('data-content').replace(inputSha256.slice(saltLen), ''));
|
||||
_decryptContent($content, salt);
|
||||
});
|
||||
};
|
||||
|
||||
// bind decryptor input enter keydown event
|
||||
this.$el.querySelector('#fixit-decryptor-input')?.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
decryptorHandler();
|
||||
}
|
||||
});
|
||||
|
||||
this.$el.querySelector('.fixit-encryptor-btn')?.addEventListener('click', function (e) {
|
||||
|
||||
// bind decryptor button click event
|
||||
this.$el.querySelector('.fixit-decryptor-btn')?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.classList.add('d-none')
|
||||
_decryptor.$el.querySelector('#fixit-decryptor-input').classList.remove('d-none');
|
||||
decryptorHandler();
|
||||
});
|
||||
|
||||
// bind encryptor button click event
|
||||
this.$el.querySelector('.fixit-encryptor-btn')?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.target.classList.add('d-none')
|
||||
this.$el.querySelector('.fixit-decryptor-input').classList.remove('d-none');
|
||||
this.$el.querySelector('.fixit-decryptor-btn').classList.remove('d-none');
|
||||
document.querySelector('#content').innerHTML = '';
|
||||
document.querySelector('#content').insertAdjacentElement(
|
||||
'afterbegin',
|
||||
_decryptor.$el
|
||||
this.$el
|
||||
);
|
||||
window.localStorage?.removeItem(`fixit-decryptor/#${location.pathname}`);
|
||||
// reset hook
|
||||
for (const event of _decryptor.resetEventSet) {
|
||||
for (const event of this.resetEventSet) {
|
||||
event();
|
||||
}
|
||||
});
|
||||
@@ -101,50 +140,31 @@ FixItDecryptor = function (options = {}) {
|
||||
* initialize fixit-encryptor shortcodes
|
||||
*/
|
||||
_proto.initShortcodes = () => {
|
||||
// TODO TODO shortcode decrypted event
|
||||
// this.addEventListener('decrypted', this.options?.decrypted);
|
||||
const _decryptor = this;
|
||||
const $shortcodes = document.querySelectorAll('fixit-encryptor:not(.decrypted)');
|
||||
customElements.get('fixit-encryptor') || customElements.define('fixit-encryptor', class extends HTMLElement {});
|
||||
const $shortcodes = document.querySelectorAll('fixit-encryptor:not(:has(.decrypted))');
|
||||
|
||||
$shortcodes.forEach($shortcode => {
|
||||
const decryptorHandler = () => {
|
||||
const $decryptor = $shortcode.querySelector('.fixit-decryptor-container');
|
||||
const $content = $shortcode.querySelector('[data-password][data-content]');
|
||||
_validatePassword($decryptor, $content, (password, salt) => {
|
||||
_decryptContent($content, salt, false);
|
||||
});
|
||||
};
|
||||
|
||||
// bind decryptor input enter keydown event
|
||||
$shortcode.querySelector('.fixit-decryptor-input')?.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
const $decryptor = this.parentElement.parentElement;
|
||||
const $content = $decryptor.nextElementSibling;
|
||||
const password = $content.getAttribute('data-password');
|
||||
const input = this.value.trim();
|
||||
const saltLen = input.length % 2 ? input.length : input.length + 1;
|
||||
const inputMd5 = CryptoJS.MD5(input).toString();
|
||||
const inputSha256 = CryptoJS.SHA256(input).toString();
|
||||
|
||||
this.value = '';
|
||||
this.blur();
|
||||
if (!input) {
|
||||
alert('Please enter the correct password!');
|
||||
return console.warn('Please enter the correct password!');
|
||||
}
|
||||
if (inputMd5 !== password) {
|
||||
alert(`Password error: ${input} not the correct password!`);
|
||||
return console.warn(`Password error: ${input} not the correct password!`);
|
||||
}
|
||||
try {
|
||||
const base64EncodeContent = $content.getAttribute('data-content').replace(inputSha256.slice(saltLen), '');
|
||||
$decryptor.querySelector('.fixit-decryptor-input').classList.add('d-none');
|
||||
$content.insertAdjacentHTML(
|
||||
'afterbegin',
|
||||
CryptoJS.enc.Base64.parse(base64EncodeContent).toString(CryptoJS.enc.Utf8)
|
||||
);
|
||||
$decryptor.parentElement.classList.add('decrypted');
|
||||
} catch (err) {
|
||||
return console.error(err);
|
||||
}
|
||||
// TODO shortcode decrypted hook
|
||||
// for (const event of _decryptor.decryptedEventSet) {
|
||||
// event();
|
||||
// }
|
||||
decryptorHandler();
|
||||
}
|
||||
});
|
||||
|
||||
// bind decryptor button click event
|
||||
$shortcode.querySelector('.fixit-decryptor-btn')?.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
decryptorHandler();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -159,17 +179,18 @@ FixItDecryptor = function (options = {}) {
|
||||
|
||||
if (!cachedStat) {
|
||||
this.$el.querySelector('.fixit-decryptor-loading').classList.add('d-none');
|
||||
this.$el.querySelector('#fixit-decryptor-input').classList.remove('d-none');
|
||||
this.$el.querySelector('.fixit-decryptor-input').classList.remove('d-none');
|
||||
this.$el.querySelector('.fixit-decryptor-btn').classList.remove('d-none');
|
||||
return this;
|
||||
}
|
||||
if (cachedStat?.md5 !== password || Number(cachedStat?.expiration) < Math.ceil(Date.now() / 1000)) {
|
||||
if (cachedStat?.password !== password || Number(cachedStat?.expiration) < Math.ceil(Date.now() / 1000)) {
|
||||
this.$el.querySelector('.fixit-decryptor-loading').classList.add('d-none');
|
||||
this.$el.querySelector('#fixit-decryptor-input').classList.remove('d-none');
|
||||
this.$el.querySelector('.fixit-decryptor-input').classList.remove('d-none');
|
||||
window.localStorage?.removeItem(`fixit-decryptor/#${location.pathname}`);
|
||||
console.warn('The password has expired, please re-enter!');
|
||||
return this;
|
||||
}
|
||||
_decryptContent($content.getAttribute('data-content').replace(cachedStat.sha256, ''));
|
||||
_decryptContent($content, cachedStat.salt);
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -187,6 +208,9 @@ FixItDecryptor = function (options = {}) {
|
||||
case 'decrypted':
|
||||
this.decryptedEventSet.add(listener);
|
||||
break;
|
||||
case 'partial-decrypted':
|
||||
this.partialDecryptedEventSet.add(listener);
|
||||
break;
|
||||
case 'reset':
|
||||
this.resetEventSet.add(listener);
|
||||
break;
|
||||
@@ -211,6 +235,9 @@ FixItDecryptor = function (options = {}) {
|
||||
case 'decrypted':
|
||||
this.decryptedEventSet.delete(listener);
|
||||
break;
|
||||
case 'partial-decrypted':
|
||||
this.partialDecryptedEventSet.delete(listener);
|
||||
break;
|
||||
case 'reset':
|
||||
this.resetEventSet.delete(listener);
|
||||
break;
|
||||
|
||||
+113
-53
@@ -3,7 +3,6 @@ import Util from './util';
|
||||
class FixIt {
|
||||
constructor() {
|
||||
this.config = window.config;
|
||||
this.data = this.config.data || [];
|
||||
this.isDark = document.body.dataset.theme === 'dark';
|
||||
this.util = new Util();
|
||||
this.newScrollTop = this.util.getScrollTop();
|
||||
@@ -49,8 +48,8 @@ class FixIt {
|
||||
});
|
||||
}
|
||||
|
||||
initTwemoji() {
|
||||
this.config.twemoji && twemoji.parse(document.body);
|
||||
initTwemoji(target = document.body) {
|
||||
this.config.twemoji && twemoji.parse(target);
|
||||
}
|
||||
|
||||
initMenu() {
|
||||
@@ -94,7 +93,7 @@ class FixIt {
|
||||
this.isDark = !this.isDark;
|
||||
window.localStorage?.setItem('theme', this.isDark ? 'dark' : 'light');
|
||||
for (let event of this.switchThemeEventSet) {
|
||||
event();
|
||||
event(this.isDark);
|
||||
}
|
||||
}, false);
|
||||
});
|
||||
@@ -234,7 +233,7 @@ class FixIt {
|
||||
const results = {};
|
||||
window._index.search(query).forEach(({ item, refIndex, matches }) => {
|
||||
let title = item.title;
|
||||
let content = item.content;
|
||||
let content = item.content.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
||||
matches.forEach(({ indices, value, key }) => {
|
||||
if (key === 'content') {
|
||||
let offset = 0;
|
||||
@@ -334,8 +333,8 @@ class FixIt {
|
||||
}
|
||||
}
|
||||
|
||||
initDetails() {
|
||||
this.util.forEach(document.getElementsByClassName('details'), ($details) => {
|
||||
initDetails(target = document) {
|
||||
this.util.forEach(target.getElementsByClassName('details'), ($details) => {
|
||||
const $summary = $details.querySelector('.details-summary');
|
||||
$summary.addEventListener('click', () => {
|
||||
$details.classList.toggle('open');
|
||||
@@ -345,7 +344,8 @@ class FixIt {
|
||||
|
||||
initLightGallery() {
|
||||
if (this.config.lightgallery) {
|
||||
lightGallery(document.getElementById('content'), {
|
||||
this.lg && this.lg.destroy(true);
|
||||
this.lg = lightGallery(document.getElementById('content'), {
|
||||
plugins: [lgThumbnail, lgZoom],
|
||||
selector: '.lightgallery',
|
||||
speed: 400,
|
||||
@@ -377,7 +377,7 @@ class FixIt {
|
||||
$preChroma.parentElement.replaceChild($chroma, $preChroma);
|
||||
$td.appendChild($preChroma);
|
||||
});
|
||||
this.util.forEach(document.querySelectorAll('.highlight > .chroma'), ($chroma) => {
|
||||
this.util.forEach(document.querySelectorAll('.highlight > .chroma:not(:has(.code-header))'), ($chroma) => {
|
||||
const $codeElements = $chroma.querySelectorAll('pre.chroma > code');
|
||||
if ($codeElements.length) {
|
||||
const $code = $codeElements[$codeElements.length - 1];
|
||||
@@ -386,8 +386,13 @@ class FixIt {
|
||||
// code title
|
||||
const $title = document.createElement('span');
|
||||
$title.classList.add('code-title');
|
||||
const hlAttrs = this.data[$chroma.parentNode.id];
|
||||
$title.insertAdjacentHTML('afterbegin', `<i class="arrow fa-solid fa-chevron-right fa-fw" aria-hidden="true"></i><span class="title-inner">${hlAttrs?.title ?? ''}</span>`);
|
||||
// insert code title inner
|
||||
$title.insertAdjacentHTML(
|
||||
'afterbegin',
|
||||
$chroma.parentNode.title
|
||||
? `<i class="arrow fa-solid fa-chevron-right fa-fw" aria-hidden="true"></i><span class="title-inner">${$chroma.parentNode.title}</span>`
|
||||
: '<i class="arrow fa-solid fa-chevron-right fa-fw" aria-hidden="true"></i>'
|
||||
);
|
||||
$title.addEventListener('click', () => {
|
||||
$chroma.classList.toggle('open');
|
||||
}, false);
|
||||
@@ -451,8 +456,8 @@ class FixIt {
|
||||
});
|
||||
}
|
||||
|
||||
initTable() {
|
||||
this.util.forEach(document.querySelectorAll('.content table'), ($table) => {
|
||||
initTable(target = document) {
|
||||
this.util.forEach(target.querySelectorAll('.content table'), ($table) => {
|
||||
const $wrapper = document.createElement('div');
|
||||
$wrapper.className = 'table-wrapper';
|
||||
$table.parentElement.replaceChild($wrapper, $table);
|
||||
@@ -544,30 +549,38 @@ class FixIt {
|
||||
}, false);
|
||||
}
|
||||
|
||||
initMath() {
|
||||
initMath(target = document.body) {
|
||||
if (this.config.math) {
|
||||
renderMathInElement(document.body, this.config.math);
|
||||
renderMathInElement(target, this.config.math);
|
||||
}
|
||||
}
|
||||
|
||||
switchMermaidTheme(theme) {
|
||||
const $mermaidElements = document.getElementsByClassName('mermaid');
|
||||
if ($mermaidElements.length) {
|
||||
// TODO perf
|
||||
const themes = this.config.mermaid.themes ?? ['default', 'dark', 'neutral'];
|
||||
mermaid.initialize({ startOnLoad: false, theme: theme ?? (this.isDark ? themes[1] : themes[0]), securityLevel: 'loose' });
|
||||
this.util.forEach($mermaidElements, $mermaid => {
|
||||
mermaid.render('svg-' + $mermaid.id, this.data[$mermaid.id], svgCode => {
|
||||
$mermaid.innerHTML = svgCode;
|
||||
}, $mermaid);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
initMermaid() {
|
||||
this.switchMermaidTheme();
|
||||
this.switchThemeEventSet.add(() => { this.switchMermaidTheme(); });
|
||||
this.beforeprintEventSet.add(() => { this.switchMermaidTheme('neutral'); });
|
||||
if (!window.mermaid?.initialize) {
|
||||
return;
|
||||
}
|
||||
const _initializeAndRun = () => {
|
||||
const themes = window.mermaid.themes ?? ['default', 'dark'];
|
||||
window.mermaid.initialize({
|
||||
securityLevel: 'loose',
|
||||
startOnLoad: false,
|
||||
theme: this.isDark ? themes[1] : themes[0],
|
||||
});
|
||||
window.mermaid.run()
|
||||
}
|
||||
_initializeAndRun()
|
||||
this.switchThemeEventSet.add(() => {
|
||||
// Reinitialize and run mermaid when theme changes.
|
||||
this.util.forEach(document.querySelectorAll('.mermaid[data-processed]'), ($mermaid) => {
|
||||
$mermaid.dataset.processed = ''
|
||||
$mermaid.innerHTML = ''
|
||||
$mermaid.appendChild($mermaid.nextElementSibling.content.cloneNode(true))
|
||||
})
|
||||
_initializeAndRun()
|
||||
});
|
||||
this.beforeprintEventSet.add(() => {
|
||||
// Set the theme to neutral when printing.
|
||||
});
|
||||
}
|
||||
|
||||
initEcharts() {
|
||||
@@ -582,11 +595,16 @@ class FixIt {
|
||||
this._echartsArr[i].dispose();
|
||||
}
|
||||
this._echartsArr = [];
|
||||
const stagingDOM = this.util.getStagingDOM()
|
||||
this.util.forEach(document.getElementsByClassName('echarts'), ($echarts) => {
|
||||
const chart = echarts.init($echarts, this.isDark ? 'dark' : 'light', { renderer: 'svg' });
|
||||
chart.setOption(JSON.parse(this.data[$echarts.id]));
|
||||
this._echartsArr.push(chart);
|
||||
if ($echarts.nextElementSibling.tagName === 'TEMPLATE') {
|
||||
const chart = echarts.init($echarts, this.isDark ? 'dark' : 'light', { renderer: 'svg' });
|
||||
stagingDOM.stage($echarts.nextElementSibling.content.cloneNode(true));
|
||||
chart.setOption(stagingDOM.contentAsJson());
|
||||
this._echartsArr.push(chart);
|
||||
}
|
||||
});
|
||||
stagingDOM.destroy();
|
||||
});
|
||||
this.switchThemeEventSet.add(this._echartsOnSwitchTheme);
|
||||
this._echartsOnSwitchTheme();
|
||||
@@ -600,11 +618,13 @@ class FixIt {
|
||||
|
||||
initMapbox() {
|
||||
if (this.config.mapbox) {
|
||||
mapboxgl.accessToken = this.config.mapbox.accessToken;
|
||||
mapboxgl.setRTLTextPlugin(this.config.mapbox.RTLTextPlugin);
|
||||
this._mapboxArr = this._mapboxArr || [];
|
||||
this.util.forEach(document.getElementsByClassName('mapbox'), ($mapbox) => {
|
||||
const { lng, lat, zoom, lightStyle, darkStyle, marked, navigation, geolocate, scale, fullscreen } = this.data[$mapbox.id];
|
||||
if (!mapboxgl.accessToken) {
|
||||
mapboxgl.accessToken = this.config.mapbox.accessToken;
|
||||
mapboxgl.setRTLTextPlugin(this.config.mapbox.RTLTextPlugin);
|
||||
this._mapboxArr = this._mapboxArr || [];
|
||||
}
|
||||
this.util.forEach(document.querySelectorAll('.mapbox:empty'), ($mapbox) => {
|
||||
const { lng, lat, zoom, lightStyle, darkStyle, marked, navigation, geolocate, scale, fullscreen } = JSON.parse($mapbox.dataset.options);
|
||||
const mapbox = new mapboxgl.Map({
|
||||
container: $mapbox,
|
||||
center: [lng, lat],
|
||||
@@ -643,7 +663,7 @@ class FixIt {
|
||||
this._mapboxOnSwitchTheme = this._mapboxOnSwitchTheme || (() => {
|
||||
this.util.forEach(this._mapboxArr, (mapbox) => {
|
||||
const $mapbox = mapbox.getContainer();
|
||||
const { lightStyle, darkStyle } = this.data[$mapbox.id];
|
||||
const { lightStyle, darkStyle } = JSON.parse($mapbox.dataset.options);
|
||||
mapbox.setStyle(this.isDark ? darkStyle : lightStyle);
|
||||
mapbox.addControl(new MapboxLanguage());
|
||||
});
|
||||
@@ -652,25 +672,45 @@ class FixIt {
|
||||
}
|
||||
}
|
||||
|
||||
initTypeit() {
|
||||
initTypeit(target = document) {
|
||||
if (this.config.typeit) {
|
||||
const typeitConfig = this.config.typeit;
|
||||
const speed = typeitConfig.speed || 100;
|
||||
const cursorSpeed = typeitConfig.cursorSpeed || 1000;
|
||||
const cursorChar = typeitConfig.cursorChar || '|';
|
||||
const loop = typeitConfig.loop ?? false;
|
||||
Object.values(typeitConfig.data).forEach((group) => {
|
||||
// divide them into different groups according to the data-group attribute value of the element
|
||||
// results in an object like {group1: [ele1, ele2], group2: [ele3, ele4]}
|
||||
const typeitElements = target.querySelectorAll('.typeit')
|
||||
const groupMap = Array.from(typeitElements).reduce((acc, ele) => {
|
||||
const group = ele.dataset.group || ele.id || Math.random().toString(36).substring(2);
|
||||
acc[group] = acc[group] || [];
|
||||
acc[group].push(ele);
|
||||
return acc;
|
||||
}, {});
|
||||
const stagingDOM = this.util.getStagingDOM()
|
||||
|
||||
Object.values(groupMap).forEach((group) => {
|
||||
const typeone = (i) => {
|
||||
const id = group[i];
|
||||
const shortcodeLoop = document.querySelector(`#${id}`).parentElement.dataset.loop;
|
||||
const instance = new TypeIt(`#${id}`, {
|
||||
strings: this.data[id],
|
||||
const typeitElement = group[i];
|
||||
const singleLoop = typeitElement.dataset.loop;
|
||||
stagingDOM.stage(typeitElement.querySelector('template').content.cloneNode(true));
|
||||
// for shortcodes usage
|
||||
let targetEle = typeitElement.firstElementChild
|
||||
// for system elements usage
|
||||
if (typeitElement.firstElementChild.tagName === 'TEMPLATE') {
|
||||
typeitElement.innerHTML = '';
|
||||
targetEle = typeitElement
|
||||
}
|
||||
// create a new instance of TypeIt for each element
|
||||
const instance = new TypeIt(targetEle, {
|
||||
strings: stagingDOM.$el.querySelector('pre')?.innerHTML || stagingDOM.contentAsHtml(),
|
||||
speed: speed,
|
||||
lifeLike: true,
|
||||
cursorSpeed: cursorSpeed,
|
||||
cursorChar: cursorChar,
|
||||
waitUntilVisible: true,
|
||||
loop: shortcodeLoop ? JSON.parse(shortcodeLoop) : loop,
|
||||
loop: singleLoop ? JSON.parse(singleLoop) : loop,
|
||||
afterComplete: () => {
|
||||
if (i === group.length - 1) {
|
||||
if (typeitConfig.duration >= 0) {
|
||||
@@ -687,6 +727,7 @@ class FixIt {
|
||||
};
|
||||
typeone(0);
|
||||
});
|
||||
stagingDOM.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -926,12 +967,28 @@ class FixIt {
|
||||
this.initEcharts();
|
||||
this.initTypeit();
|
||||
this.initMapbox();
|
||||
this.util.forEach(document.querySelectorAll('.encrypted-hidden'), ($element) => {
|
||||
$element.classList.replace('encrypted-hidden', 'decrypted-shown');
|
||||
});
|
||||
this.initToc();
|
||||
this.initTocListener();
|
||||
this.initPangu();
|
||||
this.util.forEach(document.querySelectorAll('.encrypted-hidden'), ($element) => {
|
||||
$element.classList.replace('encrypted-hidden', 'decrypted-shown');
|
||||
});
|
||||
},
|
||||
partialDecrypted: ($content) => {
|
||||
this.initTwemoji($content);
|
||||
this.initDetails($content);
|
||||
this.initLightGallery();
|
||||
this.initHighlight();
|
||||
this.initTable($content);
|
||||
this.initMath($content);
|
||||
this.initMermaid();
|
||||
this.initEcharts();
|
||||
this.initTypeit($content);
|
||||
this.initMapbox();
|
||||
this.initPangu();
|
||||
this.util.forEach($content.querySelectorAll('.encrypted-hidden'), ($element) => {
|
||||
$element.classList.replace('encrypted-hidden', 'decrypted-shown');
|
||||
});
|
||||
},
|
||||
reset: () => {
|
||||
this.util.forEach(document.querySelectorAll('.decrypted-shown'), ($element) => {
|
||||
@@ -943,6 +1000,9 @@ class FixIt {
|
||||
this.decryptor.addEventListener('decrypted', () => {
|
||||
this.decryptor.initShortcodes();
|
||||
})
|
||||
this.decryptor.addEventListener('partial-decrypted', () => {
|
||||
this.decryptor.initShortcodes();
|
||||
})
|
||||
this.decryptor.initShortcodes();
|
||||
}
|
||||
this.config.encryption?.all && this.decryptor.init();
|
||||
@@ -1101,7 +1161,6 @@ class FixIt {
|
||||
event();
|
||||
}
|
||||
this.initToc();
|
||||
this.switchMermaidTheme();
|
||||
this.initSearch();
|
||||
|
||||
const isMobile = this.util.isMobile()
|
||||
@@ -1142,7 +1201,8 @@ class FixIt {
|
||||
try {
|
||||
if (this.config.encryption) {
|
||||
this.initFixItDecryptor();
|
||||
} else if (!this.config.encryption?.all) {
|
||||
}
|
||||
if (!this.config.encryption?.all) {
|
||||
this.initTwemoji();
|
||||
this.initDetails();
|
||||
this.initLightGallery();
|
||||
|
||||
@@ -55,4 +55,35 @@ export default class Util {
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* get a hidden element for temporary use
|
||||
* @returns {Object} { $el: Element, destroy: Function }
|
||||
*/
|
||||
getStagingDOM() {
|
||||
const stagingElement = document.createElement('div')
|
||||
stagingElement.style.display = 'none';
|
||||
stagingElement.dataset.stagingId = Math.random().toString(36).slice(2);
|
||||
document.body.appendChild(stagingElement);
|
||||
|
||||
return {
|
||||
$el: stagingElement,
|
||||
stage(dom) {
|
||||
stagingElement.innerHTML = '';
|
||||
stagingElement.appendChild(dom);
|
||||
},
|
||||
contentAsHtml() {
|
||||
return stagingElement.innerHTML;
|
||||
},
|
||||
contentAsText() {
|
||||
return stagingElement.innerText;
|
||||
},
|
||||
contentAsJson() {
|
||||
return JSON.parse(stagingElement.innerHTML);
|
||||
},
|
||||
destroy() {
|
||||
document.body.removeChild(stagingElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1
-2
@@ -1,7 +1,7 @@
|
||||
algoliasearch@4.20.0 https://github.com/algolia/algoliasearch-client-javascript
|
||||
animate.css@4.1.1 https://github.com/daneden/animate.css
|
||||
aplayer@1.10.1 https://github.com/MoePlayer/APlayer
|
||||
artalk@2.6.4 https://github.com/ArtalkJS/Artalk
|
||||
artalk@latest https://github.com/ArtalkJS/Artalk
|
||||
autocomplete-js@0.38.1 https://github.com/algolia/autocomplete
|
||||
cell-watermark@1.0.3 https://github.com/Lruihao/watermark
|
||||
cookieconsent@3.1.1 https://github.com/osano/cookieconsent
|
||||
@@ -17,7 +17,6 @@ instant.page@5.2.0 https://github.com/instantpage/instant.page
|
||||
katex@0.16.9 https://github.com/KaTeX/KaTeX
|
||||
lightgallery@2.7.2 https://github.com/sachinchoolur/lightgallery
|
||||
mapbox-gl@2.10.0 https://github.com/mapbox/mapbox-gl-js
|
||||
mermaid@9.4.3 https://github.com/mermaid-js/mermaid
|
||||
meting@2.0.1 https://github.com/metowolf/MetingJS
|
||||
normalize.css@8.0.1 https://github.com/necolas/normalize.css
|
||||
object-fit-images@3.2.4 https://github.com/fregante/object-fit-images [archived]
|
||||
|
||||
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1580
File diff suppressed because one or more lines are too long
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: My First Post
|
||||
date: 2023-02-20T20:14:22+08:00
|
||||
draft: false
|
||||
---
|
||||
|
||||
A blog (a truncation of "weblog") is an informational website published on the World Wide Web consisting of discrete, often informal diary-style text entries (posts). Posts are typically displayed in reverse chronological order so that the most recent post appears first, at the top of the web page. Until 2009, blogs were usually the work of a single individual,[citation needed] occasionally of a small group, and often covered a single subject or topic. In the 2010s, "multi-author blogs" (MABs) emerged, featuring the writing of multiple authors and sometimes professionally edited. MABs from newspapers, other media outlets, universities, think tanks, advocacy groups, and similar institutions account for an increasing quantity of blog traffic. The rise of Twitter and other "microblogging" systems helps integrate MABs and single-author blogs into the news media. Blog can also be used as a verb, meaning to maintain or add content to a blog.
|
||||
@@ -0,0 +1,55 @@
|
||||
# -------------------------------------------------------------------------------------
|
||||
# The following is a necessary configuration for the FixIt theme.
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
title = "My Hugo FixIt Site"
|
||||
baseURL = "http://example.org/"
|
||||
# Change the default theme to be use when building the site with Hugo
|
||||
# theme = "FixIt"
|
||||
|
||||
[markup]
|
||||
# Syntax Highlighting (https://gohugo.io/content-management/syntax-highlighting)
|
||||
[markup.highlight]
|
||||
########## necessary configurations ##########
|
||||
# https://github.com/hugo-fixit/FixIt/issues/43
|
||||
codeFences = true
|
||||
lineNos = true
|
||||
lineNumbersInTable = true
|
||||
noClasses = false
|
||||
########## necessary configurations ##########
|
||||
guessSyntax = true
|
||||
# Goldmark is from Hugo 0.60 the default library used for Markdown
|
||||
[markup.goldmark]
|
||||
[markup.goldmark.extensions]
|
||||
definitionList = true
|
||||
footnote = true
|
||||
linkify = true
|
||||
strikethrough = true
|
||||
table = true
|
||||
taskList = true
|
||||
typographer = true
|
||||
[markup.goldmark.renderer]
|
||||
# whether to use HTML tags directly in the document
|
||||
unsafe = true
|
||||
# Table Of Contents settings
|
||||
[markup.tableOfContents]
|
||||
ordered = false
|
||||
startLevel = 2
|
||||
endLevel = 6
|
||||
|
||||
[outputs]
|
||||
home = ["HTML", "RSS", "JSON", "archives"]
|
||||
page = ["HTML", "MarkDown"]
|
||||
section = ["HTML", "RSS"]
|
||||
taxonomy = ["HTML"]
|
||||
term = ["HTML", "RSS"]
|
||||
|
||||
# -------------------------------------------------------------------------------------
|
||||
# Theme Core Configuration
|
||||
# See: https://fixit.lruihao.cn/documentation/basics/#theme-configuration
|
||||
# -------------------------------------------------------------------------------------
|
||||
|
||||
[params]
|
||||
# FixIt theme version
|
||||
version = "0.3.X" # e.g. "0.2.X", "0.2.15", "v0.2.15" etc.
|
||||
# ...
|
||||
-1
Submodule docs deleted from 483d685a80
+3
-3
@@ -3,11 +3,11 @@
|
||||
"https://fixit.lruihao.cn",
|
||||
"https://pre.fixit.lruihao.cn",
|
||||
"https://hugofixit.vercel.app",
|
||||
"https://fixit-x-cell.vercel.app"
|
||||
"https://docs-cell-x.vercel.app"
|
||||
],
|
||||
"originsRegex": [
|
||||
"https://fixit-git-([A-z0-9]|-)*x-cell\\.vercel\\.app",
|
||||
"https://fixit-[A-z0-9]{9}-x-cell\\.vercel\\.app",
|
||||
"https://docs-git-([A-z0-9]|-)*cell-x\\.vercel\\.app",
|
||||
"https://docs-[A-z0-9]{9}-cell-x\\.vercel\\.app",
|
||||
"http://localhost:[0-9]+"
|
||||
],
|
||||
"defaultCommentOrder": "oldest"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# =====================================================================================
|
||||
# It's recommended to use Alternate Theme Config to configure FixIt
|
||||
# Modifying this file may result in merge conflict
|
||||
# There are currently some restrictions to what a theme component can configure:
|
||||
# params, menu, outputformats and mediatypes
|
||||
# =====================================================================================
|
||||
|
||||
# -------------------------------------------------------------------------------------
|
||||
@@ -13,7 +15,7 @@ title = ""
|
||||
# Hostname (and path) to the root
|
||||
baseURL = "http://localhost:1313"
|
||||
# theme list
|
||||
theme = ["FixIt"]
|
||||
# theme = ["FixIt"] # enable in your site config file
|
||||
# determines default content language ["en", "zh-cn", "fr", "pl", ...]
|
||||
defaultContentLanguage = "en"
|
||||
# language code ["en", "zh-CN", "fr", "pl", ...]
|
||||
@@ -40,13 +42,14 @@ enableEmoji = true
|
||||
|
||||
[menu]
|
||||
[[menu.main]]
|
||||
identifier = "posts"
|
||||
identifier = "archives"
|
||||
parent = ""
|
||||
# you can add extra information before the name (HTML format is supported), such as icons
|
||||
pre = ""
|
||||
# you can add extra information after the name (HTML format is supported), such as icons
|
||||
post = ""
|
||||
name = "Posts"
|
||||
url = "/posts/"
|
||||
name = "Archives"
|
||||
url = "/archives/"
|
||||
# title will be shown when you hover on this menu link
|
||||
title = ""
|
||||
weight = 1
|
||||
@@ -62,6 +65,7 @@ enableEmoji = true
|
||||
type = ""
|
||||
[[menu.main]]
|
||||
identifier = "categories"
|
||||
parent = ""
|
||||
pre = ""
|
||||
post = ""
|
||||
name = "Categories"
|
||||
@@ -72,6 +76,7 @@ enableEmoji = true
|
||||
icon = "fa-solid fa-folder-tree"
|
||||
[[menu.main]]
|
||||
identifier = "tags"
|
||||
parent = ""
|
||||
pre = ""
|
||||
post = ""
|
||||
name = "Tags"
|
||||
@@ -260,7 +265,7 @@ enableEmoji = true
|
||||
# taxonomy: ["HTML", "RSS"]
|
||||
# term: ["HTML", "RSS"]
|
||||
[outputs]
|
||||
home = ["HTML", "RSS", "JSON", "archives", "offline"]
|
||||
home = ["HTML", "RSS", "JSON", "archives"]
|
||||
page = ["HTML", "MarkDown"]
|
||||
section = ["HTML", "RSS"]
|
||||
taxonomy = ["HTML"]
|
||||
@@ -283,7 +288,7 @@ enableEmoji = true
|
||||
|
||||
[params]
|
||||
# FixIt 0.2.15 | CHANGED FixIt theme version
|
||||
version = "0.2.X" # e.g. "0.2.X", "0.2.15", "v0.2.15" etc.
|
||||
version = "0.3.X" # e.g. "0.2.X", "0.2.15", "v0.2.15" etc.
|
||||
# site description
|
||||
description = ""
|
||||
# site keywords
|
||||
@@ -693,6 +698,8 @@ enableEmoji = true
|
||||
[params.page.heading.number]
|
||||
# whether to enable auto heading numbering
|
||||
enable = false
|
||||
# FixIt 0.3.3 | NEW only enable in main section pages (default is posts)
|
||||
onlyMainSection = true
|
||||
[params.page.heading.number.format]
|
||||
h1 = "{title}"
|
||||
h2 = "{h2} {title}"
|
||||
@@ -795,6 +802,8 @@ enableEmoji = true
|
||||
enable = false
|
||||
server = "https://yourdomain"
|
||||
site = "默认站点"
|
||||
# FixIt 0.3.3 | NEW whether use backend configuration
|
||||
useBackendConf = false
|
||||
placeholder = ""
|
||||
noComment = ""
|
||||
sendBtn = ""
|
||||
|
||||
@@ -129,6 +129,7 @@ expirationReminder = "Dieser Artikel wurde zuletzt auf {{ .Date }} aktualisiert,
|
||||
encryptedAbstract = ""
|
||||
encryptedMessage = ""
|
||||
password = "Passwort"
|
||||
enterBtn = ""
|
||||
encryptyAgain = ""
|
||||
relatedContent = "Ähnliche Inhalte"
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ expirationReminder = "This article was last updated on {{ .Date }}, the content
|
||||
encryptedAbstract = "This article has been encrypted, so its raw content is invisible!"
|
||||
encryptedMessage = "Please enter the password"
|
||||
password = "Password"
|
||||
enterBtn = "Enter"
|
||||
encryptyAgain = "Encrypt again"
|
||||
relatedContent = "Related Content"
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ expirationReminder = "Este artículo se actualizó por última vez el {{ .Date }
|
||||
encryptedAbstract = ""
|
||||
encryptedMessage = ""
|
||||
password = "Contraseña"
|
||||
enterBtn = ""
|
||||
encryptyAgain = ""
|
||||
relatedContent = "Contenido relacionado"
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ expirationReminder = "Cet article a été mis à jour pour la dernière fois le
|
||||
encryptedAbstract = "Cet article a été chiffré, son contenu n'est donc pas lisible!"
|
||||
encryptedMessage = "Entrer le mot de passe"
|
||||
password = "Mot de passe"
|
||||
enterBtn = "Entrer"
|
||||
encryptyAgain = "Chiffrer à nouveau"
|
||||
relatedContent = "Contenu lié"
|
||||
|
||||
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
# Translations for Hindi
|
||||
# हिंदी के लिए अनुवाद
|
||||
# https://gohugo.io/content-management/multilingual/#translation-of-strings
|
||||
|
||||
# === init ===
|
||||
[init]
|
||||
configurationError = "कन्फ़िग्यरेशन त्रुटि \nआपने फिक्सइट संस्करण पैरामीटर को सही ढंग से कॉन्फ़िगर नहीं किया है।. यह देखें: https://fixit.lruihao.cn/documentation/basics/#theme-configuration"
|
||||
compatibilityError = "संगतता त्रुटि ({{ .From }} -> {{ .To }}):\nआपके पास एक असंगत अपडेट है. यह देखें: https://github.com/hugo-fixit/FixIt/releases"
|
||||
RCVersionWarn = "आप फिक्सइट के डिवेलपर संस्करण का उपयोग कर रहे हैं। कृपया एक स्थिर संस्करण का उपयोग करने पर विचार करें।\nयह देखें: https://github.com/hugo-fixit/FixIt/releases"
|
||||
devEnvWarn = "वर्तमान परिवेश \"डिवेलप्मेंट\" का है। \"टिप्पणी प्रणाली\", \"सीडीएन\" और \"फ़िंगरप्रिंट\" अक्षम कर दिए जाएंगे। "
|
||||
quicklyUpgrade = "शीघ्रता से अपग्रेड यह कमांड का उपयोग करें: "
|
||||
# === init ===
|
||||
|
||||
# === baseof ===
|
||||
[baseof]
|
||||
backToTop = "वापस शीर्ष पर"
|
||||
viewComments = "टिप्पणियाँ देखें"
|
||||
noscript = "फिक्सइट थीम जावास्क्रिप्ट सक्षम होने पर सबसे अच्छा काम करता है।"
|
||||
# === baseof ===
|
||||
|
||||
# === Taxonomy ===
|
||||
[archives]
|
||||
other = "अभिलेखागार"
|
||||
|
||||
[allSome]
|
||||
other = "सभी {{ .Some }}"
|
||||
|
||||
[category]
|
||||
other = "श्रेणी"
|
||||
|
||||
[categories]
|
||||
other = "श्रेणियाँ"
|
||||
|
||||
[collection]
|
||||
other = "संग्रह"
|
||||
|
||||
[collections]
|
||||
other = "संग्रह"
|
||||
|
||||
[tag]
|
||||
other = "टैग"
|
||||
|
||||
[tags]
|
||||
other = "टैग "
|
||||
|
||||
[posts]
|
||||
other = "पदों"
|
||||
|
||||
# === Taxonomy ===
|
||||
|
||||
# === Section ===
|
||||
[section]
|
||||
recentlyUpdated = "हाल ही में अपडेट किया गया"
|
||||
|
||||
[section.totalWordCount]
|
||||
one = "कुल एक शब्द"
|
||||
other = "कुल {{ .Count }} शब्द"
|
||||
|
||||
[section.archiveCounter]
|
||||
one = "केवल एक लेख"
|
||||
other = "कुल {{ .Count }} लेख"
|
||||
# === Section ===
|
||||
|
||||
# === Pagination ===
|
||||
[pagination]
|
||||
more = "और देखें"
|
||||
# === Pagination ===
|
||||
|
||||
# === partials/header.html ===
|
||||
[header]
|
||||
selectLanguage = "भाषा चुने"
|
||||
noMoretTranslations = "कोई और अनुवाद नहीं"
|
||||
switchTheme = "थीम बदलें"
|
||||
# === partials/header.html ===
|
||||
|
||||
# === partials/footer.html ===
|
||||
[footer]
|
||||
poweredBySome = "{{ .Hugo }} के द्वारा संचालित | थीम - {{ .Theme }}"
|
||||
siteUV = "कुल विज़िटर"
|
||||
sitePV = "कुल विज़िट"
|
||||
siteRunning = "वेबसाइट चल रही है ..."
|
||||
# === partials/footer.html ===
|
||||
|
||||
# === partials/comment.html ===
|
||||
[comment]
|
||||
valineLang = "hi"
|
||||
valinePlaceholder = "आपकी टिप्पणी ..."
|
||||
facebookLanguageCode = "hi"
|
||||
# === partials/comment.html ===
|
||||
|
||||
# === partials/assets.html ===
|
||||
[assets]
|
||||
search = "खोज"
|
||||
searchPlaceholder = "शीर्षक या सामग्री खोजें ..."
|
||||
clear = "साफ़ करें"
|
||||
cancel = "रद्द करें"
|
||||
noResultsFound = "कोई परिणाम नहीं मिला"
|
||||
copyToClipboard = "क्लिपबोर्ड पर कॉपी करें"
|
||||
editLockTitle = "संपादन योग्य कोड ब्लॉक को लॉक करें"
|
||||
editUnLockTitle = "संपादन योग्य कोड ब्लॉक को अनलॉक करें"
|
||||
cookieconsentMessage = "यह वेबसाइट आपके अनुभव को बेहतर बनाने के लिए कुकीज़ का उपयोग करती है।"
|
||||
cookieconsentDismiss = "समझ गया!"
|
||||
cookieconsentLink = "और अधिक जानें"
|
||||
# === partials/assets.html ===
|
||||
|
||||
# === partials/plugin/share.html ===
|
||||
[shareOn]
|
||||
other = " शेयर करें"
|
||||
# === partials/plugin/share.html ===
|
||||
|
||||
# === posts/single.html ===
|
||||
[single]
|
||||
contents = "सामग्री"
|
||||
pin = "शीर्ष पर पिन करें"
|
||||
repost = "दोबारा पोस्ट करें"
|
||||
publishedOnDate = "{{ .Date }} पर प्रकाशित"
|
||||
views = "दृश्य"
|
||||
comments = "टिप्पणियाँ"
|
||||
author = "रचयिता"
|
||||
updatedOnDate = "{{ .Date }} पर अपडेट"
|
||||
readMarkdown = "मार्कडाउन पढ़ें"
|
||||
viewSource = "स्रोत देखें"
|
||||
editThisPage = "इस पृष्ठ को संपादित करें"
|
||||
reportIssue = "समस्या की रिपोर्ट करें"
|
||||
back = "पीछे"
|
||||
home = "घर"
|
||||
readMore = "और पढ़ें"
|
||||
expirationReminder = "यह लेख अंतिम बार {{ .Date }} पर अद्यतन किया गया था, सामग्री पुरानी हो सकती है."
|
||||
encryptedAbstract = "यह लेख एन्क्रिप्ट किया गया है, इसलिए इसकी मूल सामग्री अदृश्य है!"
|
||||
encryptedMessage = "कृपया पासवर्ड दर्ज करें"
|
||||
password = "पासवर्ड"
|
||||
enterBtn = "दर्ज करें"
|
||||
encryptyAgain = "फिर से एन्क्रिप्ट करें"
|
||||
relatedContent = "संबंधित सामग्री"
|
||||
|
||||
[single.includedIn]
|
||||
categories = "{{ .Categories }} में शामिल"
|
||||
collections = "{{ .Collections }} में शामिल"
|
||||
both = "{{ .Categories }} और {{ .Collections }} में शामिल"
|
||||
|
||||
[single.wordCount]
|
||||
one = "एक शब्द "
|
||||
other = "{{ .Count }} शब्द "
|
||||
|
||||
[single.fuzzyWordCount]
|
||||
other = "लगभग {{ .Count }} शब्द"
|
||||
|
||||
[single.readingTime]
|
||||
one = "एक मिनट"
|
||||
other = "{{ .Count }} मिनट"
|
||||
|
||||
[single.reward]
|
||||
donate = "दान करें"
|
||||
wechatpay = "वीचैट पे"
|
||||
alipay = "अली पे"
|
||||
paypal = "पेपैल"
|
||||
bitcoin = "बिटकॉइन"
|
||||
# === posts/single.html ===
|
||||
|
||||
# === 404.html ===
|
||||
[pageNotFound]
|
||||
other = "पृष्ठ नहीं मिला"
|
||||
|
||||
[pageNotFoundText]
|
||||
other = "आप जिस पृष्ठ को खोज रहे हैं वह मौजूद नहीं है। क्षमा मांगना।"
|
||||
# === 404.html ===
|
||||
|
||||
# === offline ===
|
||||
[offlineTitle]
|
||||
other = "ऑफलाइन"
|
||||
|
||||
[offlineText]
|
||||
other = "आप इंटरनेट से कनेक्ट नहीं हैं, केवल कैश्ड पेज ही उपलब्ध होंगे।"
|
||||
# === offline ===
|
||||
|
||||
# === shortcodes/admonition.html ===
|
||||
[admonition]
|
||||
note = "ध्यान दें"
|
||||
abstract = "सारांश"
|
||||
info = "जानकारी"
|
||||
tip = "टिप"
|
||||
success = "सफलता"
|
||||
question = "प्रश्न"
|
||||
warning = "चेतावनी"
|
||||
failure = "असफलता"
|
||||
danger = "खतरा"
|
||||
bug = "बग"
|
||||
example = "उदाहरण"
|
||||
quote = "उद्धरण"
|
||||
# === shortcodes/admonition.html ===
|
||||
|
||||
# === shortcodes/version.html ===
|
||||
[version]
|
||||
new = "नया"
|
||||
changed = "बदला हुआ"
|
||||
deleted = "हटाए गए"
|
||||
# === shortcodes/version.html ===
|
||||
@@ -129,6 +129,7 @@ expirationReminder = "Questo articolo è stato aggiornato l'ultima volta il {{ .
|
||||
encryptedAbstract = ""
|
||||
encryptedMessage = ""
|
||||
password = "Password"
|
||||
enterBtn = ""
|
||||
encryptyAgain = ""
|
||||
relatedContent = "Contenuti correlati"
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ expirationReminder = "Ten artykuł był ostatnio aktualizowany {{ .Date }}, jego
|
||||
encryptedAbstract = ""
|
||||
encryptedMessage = ""
|
||||
password = "Hasło"
|
||||
enterBtn = ""
|
||||
encryptyAgain = ""
|
||||
relatedContent = "Powiązane treści"
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ expirationReminder = "Este artigo foi atualizado pela última vez em {{ .Date }}
|
||||
encryptedAbstract = ""
|
||||
encryptedMessage = ""
|
||||
password = "Contrasinha"
|
||||
enterBtn = ""
|
||||
encryptyAgain = ""
|
||||
relatedContent = "Conteúdo relacionado"
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ expirationReminder = "Acest articol a fost actualizat ultima dată pe {{ .Date }
|
||||
encryptedAbstract = ""
|
||||
encryptedMessage = ""
|
||||
password = "Parolă"
|
||||
enterBtn = ""
|
||||
encryptyAgain = ""
|
||||
relatedContent = "Conținut înrudit"
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ expirationReminder = "Эта статья последний раз обновл
|
||||
encryptedAbstract = ""
|
||||
encryptedMessage = ""
|
||||
password = "арготизм"
|
||||
enterBtn = ""
|
||||
encryptyAgain = ""
|
||||
relatedContent = "Связанный контент"
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ expirationReminder = "Овај чланак је последњи пут ажу
|
||||
encryptedAbstract = ""
|
||||
encryptedMessage = ""
|
||||
password = "Паролица"
|
||||
enterBtn = ""
|
||||
encryptyAgain = ""
|
||||
relatedContent = "Повезани садржај"
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ expirationReminder = "Bài viết này được cập nhật lần cuối vào {
|
||||
encryptedAbstract = ""
|
||||
encryptedMessage = ""
|
||||
password = "Mật khẩu"
|
||||
enterBtn = ""
|
||||
encryptyAgain = ""
|
||||
relatedContent = "Nội dung liên quan"
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ expirationReminder = "本文最后更新于 {{ .Date }},文中内容可能已
|
||||
encryptedAbstract = "本文已加密,因此其原始内容不可见!"
|
||||
encryptedMessage = "请输入密码"
|
||||
password = "密码"
|
||||
enterBtn = "进入"
|
||||
encryptyAgain = "重新加密"
|
||||
relatedContent = "相关内容"
|
||||
|
||||
|
||||
@@ -126,6 +126,7 @@ expirationReminder = "本文最後更新於 {{ .Date }},文中內容可能已
|
||||
encryptedAbstract = "本文已加密,囙此其原始內容不可見!"
|
||||
encryptedMessage = "請輸入密碼"
|
||||
password = "密碼"
|
||||
enterBtn = "進入"
|
||||
encryptyAgain = "重新加密"
|
||||
relatedContent = "相關內容"
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 149 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
@@ -1,3 +1,5 @@
|
||||
{{- $id := dict "Content" (trim (partial "function/dos2unix.html" .Inner) "\n") "Scratch" .Page.Scratch | partial "function/id.html" -}}
|
||||
<div class="mermaid" id="{{ $id }}"></div>
|
||||
{{- .Page.Scratch.SetInMap "this" "mermaid" true -}}
|
||||
<pre class="mermaid">
|
||||
{{- .Inner | safeHTML }}
|
||||
</pre>
|
||||
<template>{{- .Inner | safeHTML }}</template>
|
||||
{{- .Page.Store.Set "hasMermaid" true -}}
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
{{- $id := dict "Content" .Attributes "Scratch" .Page.Scratch | partial "function/id.html" -}}
|
||||
{{- $codeBlock := transform.Highlight .Inner .Type .Options -}}
|
||||
{{- replace $codeBlock "<div class=\"highlight\">" (printf "<div class=\"highlight\" id=\"%v\">" $id) 1 | safeHTML -}}
|
||||
{{- $result := transform.HighlightCodeBlock . -}}
|
||||
{{- $result.Wrapped -}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{- /* Read the config and format */ -}}
|
||||
{{- $params := .Page.Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- $h1Format := $params.heading.number.format.h1 | default "{title}" -}}
|
||||
{{- $h2Format := $params.heading.number.format.h2 | default "{h2} {title}" -}}
|
||||
{{- $h3Format := $params.heading.number.format.h3 | default "{h2}.{h3} {title}" -}}
|
||||
@@ -15,7 +15,10 @@
|
||||
<h{{ .Level }} id="{{ .Anchor | safeURL }}" class="heading-element">
|
||||
<a href="#{{ .Anchor | safeURL }}" class="heading-mark"></a>
|
||||
|
||||
{{- if $params.heading.number.enable -}}
|
||||
|
||||
{{- /* Only enable in main section pages */ -}}
|
||||
{{- $onlyMainSection := cond $params.heading.number.onlyMainSection (eq .Page.Type "posts") true -}}
|
||||
{{- if $params.heading.number.enable | and $onlyMainSection -}}
|
||||
{{- /* Add 1 to the current level */ -}}
|
||||
{{- $headingMap := .Page.Scratch.Get "heading-counter" -}}
|
||||
{{- $count := (string .Level) | index $headingMap | int | add 1 -}}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
{{- $params := .Page.Params | merge site.Params.page -}}
|
||||
{{- if .Title | and .Text -}}
|
||||
{{- $linked := ne $params.lightgallery false -}}
|
||||
<figure>
|
||||
{{- dict "Src" .Destination "Alt" .Text "Caption" .Text "Title" .Title "Linked" true "Responsive" true | partial "plugin/image.html" -}}
|
||||
{{- dict "Src" .Destination "Alt" .Text "Caption" .Text "Title" .Title "Linked" $linked "Responsive" true | partial "plugin/image.html" -}}
|
||||
<figcaption class="image-caption">
|
||||
{{- .Text | safeHTML -}}
|
||||
</figcaption>
|
||||
</figure>
|
||||
{{- else -}}
|
||||
{{- $linked := (eq (.Page.Scratch.Get "params").lightgallery "force") | or (ne .Title "") -}}
|
||||
{{- $linked := (eq $params.lightgallery "force") | or ($params.lightgallery | and (ne .Title "")) -}}
|
||||
{{- dict "Src" .Destination "Alt" .Text "Title" .Title "Linked" $linked "Responsive" true | partial "plugin/image.html" -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
<script>(window.localStorage?.getItem('theme') ? localStorage.getItem('theme') === 'dark' : ('{{ $theme }}' === 'auto' ? window.matchMedia('(prefers-color-scheme: dark)').matches : '{{ $theme }}' === 'dark')) && document.body.setAttribute('data-theme', 'dark');</script>
|
||||
|
||||
{{- /* Body wrapper */ -}}
|
||||
<div class="wrapper" data-page-style="{{ (.Scratch.Get `params`).pageStyle | default `normal` }}">
|
||||
<div class="wrapper" data-page-style="{{ (partial `function/params.html`).pageStyle | default `normal` }}">
|
||||
{{- partial "header.html" . -}}
|
||||
{{- partial "breadcrumb.html" . -}}
|
||||
{{- $toc := .Scratch.Get "toc" -}}
|
||||
<main class="container{{ if (eq $toc.enable true) | and (eq $toc.position `left`) }} container-reverse{{ end }}">
|
||||
{{- block "content" . }}{{ end -}}
|
||||
</main>
|
||||
{{- partial "footer.html" . -}}
|
||||
{{- partialCached "footer.html" . -}}
|
||||
</div>
|
||||
|
||||
{{- /* Theme widgets */ -}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- define "content" -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
<article class="page single special">
|
||||
<div class="header">
|
||||
{{- /* Title */ -}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $author := .Scratch.Get "author" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- $author := .Store.Get "author" -}}
|
||||
# {{ .Title }}
|
||||
|
||||
{{ if $params.password -}}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{{ end -}}
|
||||
|
||||
{{- define "content" -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
<article class="page single special friends">
|
||||
<div class="header">
|
||||
{{- /* Title */ -}}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{{- define "content" -}}
|
||||
{{- /* All Posts */ -}}
|
||||
{{- $pages := where .Site.RegularPages "Type" "posts" -}}
|
||||
{{- $pages := .Scratch.Get "mainSectionPages" -}}
|
||||
|
||||
<div class="page archive">
|
||||
<div class="header">
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- define "content" -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- $profile := .Site.Params.home.profile -}}
|
||||
{{- $posts := .Site.Params.home.posts -}}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{{- /* Posts */ -}}
|
||||
{{- if ne $posts.enable false | and .Site.RegularPages -}}
|
||||
{{- /* Paginate */ -}}
|
||||
{{- $pages := where .Site.RegularPages "Type" "posts" -}}
|
||||
{{- $pages := .Scratch.Get "mainSectionPages" -}}
|
||||
{{- if .Site.Params.page.hiddenFromHomePage -}}
|
||||
{{- $pages = where $pages "Params.hiddenfromhomepage" false -}}
|
||||
{{- else -}}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
{{- if .Site.Params.search -}}
|
||||
{{- if .Site.Params.search.enable -}}
|
||||
{{- $index := slice -}}
|
||||
{{- $pages := where .Site.RegularPages "Params.password" "eq" nil -}}
|
||||
{{- if .Site.Params.page.hiddenFromSearch -}}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# {{ .Site.Title }}
|
||||
|
||||
{{ $pages := where .Site.RegularPages "Type" "posts" -}}
|
||||
{{ $pages := .Scratch.Get "mainSectionPages" -}}
|
||||
{{- $pages = where $pages "Draft" "eq" false -}}
|
||||
{{- T "section.archiveCounter" (len $pages) }}
|
||||
{{ range $pages.GroupByPublishDate "2006" }}
|
||||
{{- if ne .Key "0001" -}}
|
||||
{{- printf "\n## %v\n\n" .Key -}}
|
||||
{{- printf "\n## %v\n\n%v\n\n" .Key (T "section.archiveCounter" .Pages.Len) -}}
|
||||
{{- range .Pages -}}
|
||||
{{- printf "- %v [%v](%v \"%v\")\n" (.PublishDate.Format "01-02") .Title .Permalink (.PublishDate.Format "2006-01-02 15:04:05") -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
{{ with .OutputFormats.Get "RSS" }}
|
||||
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
|
||||
{{ end }}
|
||||
{{- range where .Site.RegularPages "Type" "posts" | first (.Site.Params.home.rss | default 10) -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- range .Scratch.Get "mainSectionPages" | first (.Site.Params.home.rss | default 10) -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- if $params.password | or $params.hiddenFromRss }}{{ continue }}{{ end -}}
|
||||
{{- dict "Page" . "Site" .Site | partial "rss/item.html" -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- define "content" -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
<article class="page single special friends">
|
||||
<div class="header">
|
||||
{{- /* Title */ -}}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- $cdn := .Scratch.Get "cdn" | default dict -}}
|
||||
{{- $fingerprint := .Scratch.Get "fingerprint" -}}
|
||||
{{- $config := (.Scratch.Get "this").config -}}
|
||||
{{- $config = dict "version" (.Scratch.Get "version") | merge $config -}}
|
||||
|
||||
{{- /* Search */ -}}
|
||||
{{- if .Site.Params.search | and .Site.Params.search.enable -}}
|
||||
@@ -70,11 +71,11 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- /* TypeIt */ -}}
|
||||
{{- with (.Scratch.Get "this").typeitMap -}}
|
||||
{{- $typeit := $.Site.Params.typeit -}}
|
||||
{{- if .Store.Get "hasTyped" -}}
|
||||
{{- $typeit := .Site.Params.typeit -}}
|
||||
{{- $source := $cdn.typeitJS | default "lib/typeit/index.umd.js" -}}
|
||||
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Scratch" $.Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- $config = dict "speed" $typeit.speed "cursorSpeed" $typeit.cursorSpeed "cursorChar" $typeit.cursorChar "duration" $typeit.duration "loop" $typeit.loop "data" . | dict "typeit" | merge $config -}}
|
||||
{{- $config = dict "speed" $typeit.speed "cursorSpeed" $typeit.cursorSpeed "cursorChar" $typeit.cursorChar "duration" $typeit.duration "loop" $typeit.loop | dict "typeit" | merge $config -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* KaTeX */ -}}
|
||||
@@ -114,15 +115,16 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- /* mermaid */ -}}
|
||||
{{- if (.Scratch.Get "this").mermaid -}}
|
||||
{{- $source := $cdn.mermaidJS | default "lib/mermaid/mermaid.min.js" -}}
|
||||
{{- dict "Source" $source "Fingerprint" $fingerprint | dict "Scratch" .Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- $mermaid := .Site.Params.mermaid -}}
|
||||
{{- $config = dict "themes" $mermaid.themes | dict "mermaid" | merge $config -}}
|
||||
{{- if .Store.Get "hasMermaid" -}}
|
||||
<script type="module">
|
||||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
|
||||
window.mermaid = mermaid;
|
||||
window.mermaid.themes = {{ .Site.Params.mermaid.themes }};
|
||||
</script>
|
||||
{{- end -}}
|
||||
|
||||
{{- /* ECharts */ -}}
|
||||
{{- if (.Scratch.Get "this").echarts -}}
|
||||
{{- if .HasShortcode "echarts" -}}
|
||||
{{- $source := $cdn.echartsJS | default "lib/echarts/echarts.min.js" -}}
|
||||
{{- dict "Source" $source "Fingerprint" $fingerprint "Defer" true | dict "Scratch" .Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- $lightTheme := resources.Get "lib/echarts/theme/light.yml" | transform.Unmarshal -}}
|
||||
@@ -131,7 +133,7 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Mapbox GL */ -}}
|
||||
{{- if (.Scratch.Get "this").mapbox -}}
|
||||
{{- if .HasShortcode "mapbox" -}}
|
||||
{{- $source := $cdn.mapboxGLCSS | default "lib/mapbox-gl/mapbox-gl.css" -}}
|
||||
{{- dict "Source" $source "Minify" true "Fingerprint" $fingerprint "Preload" true | dict "Scratch" .Scratch "Data" | partial "scratch/style.html" -}}
|
||||
{{- $source = $cdn.mapboxGLJS | default "lib/mapbox-gl/mapbox-gl.js" -}}
|
||||
@@ -141,7 +143,7 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Music */ -}}
|
||||
{{- if (.Scratch.Get "this").music -}}
|
||||
{{- if .HasShortcode "music" -}}
|
||||
{{- /* APlayer */ -}}
|
||||
{{- $source := $cdn.aplayerCSS | default "lib/aplayer/APlayer.min.css" -}}
|
||||
{{- dict "Source" $source "Fingerprint" $fingerprint "Preload" true | dict "Scratch" .Scratch "Data" | partial "scratch/style.html" -}}
|
||||
@@ -183,7 +185,7 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Content Decryption */ -}}
|
||||
{{- $encryptPartial := (.Scratch.Get "this").encryptPartial -}}
|
||||
{{- $encryptPartial := .HasShortcode "fixit-encryptor" -}}
|
||||
{{- if $params.password | or $encryptPartial -}}
|
||||
{{- $cryptoCoreJS := $cdn.cryptoCoreJS | default "lib/crypto-js/core.js" -}}
|
||||
{{- $cryptoEncBase64JS := $cdn.cryptoEncBase64JS | default "lib/crypto-js/enc-base64.js" -}}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- /* How to use */ -}}
|
||||
{{- /* partial "function/format-number" (dict "PRECISION" 2 "NUMBER" 5201314 */ -}}
|
||||
{{- $number := .NUMBER -}}
|
||||
{{- $precision := .PRECISION | default 1 -}}
|
||||
{{- with $number -}}
|
||||
{{- if ge . 1000 -}}
|
||||
{{- $number = printf "%vk" (lang.FormatNumberCustom $precision (div . 1000.0) "- .") -}}
|
||||
{{ printf "%v" $number }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- return $number -}}
|
||||
@@ -0,0 +1,12 @@
|
||||
{{- $response := dict -}}
|
||||
{{- with resources.GetRemote .URL .OPTIONS -}}
|
||||
{{- with .Err -}}
|
||||
{{- erroridf "error-get-remote-json" "%s" . -}}
|
||||
{{- else -}}
|
||||
{{- $response = .Content | transform.Unmarshal -}}
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
{{- erroridf "error-get-remote-json" "Unable to get remote resource %q" .URL -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- return $response -}}
|
||||
@@ -8,7 +8,4 @@
|
||||
{{- $id = printf "id-%d" $count -}}
|
||||
{{- $count | add 1 | $.Scratch.SetInMap "this" "count" -}}
|
||||
{{- end -}}
|
||||
{{- with .Content -}}
|
||||
{{- dict $id . | dict "data" | dict "config" | merge ($.Scratch.Get "this") | $.Scratch.Set "this" -}}
|
||||
{{- end -}}
|
||||
{{- return $id -}}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
{{- $params := page.Params | merge site.Params.page -}}
|
||||
{{- return $params -}}
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
|
||||
<meta name="author" content="{{ .Site.Params.author.name }}">
|
||||
<meta name="author-link" content="{{ .Site.Params.author.link }}">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
|
||||
{{- with .Site.Params.verification.google -}}
|
||||
<meta name="google-site-verification" content="{{ . }}" />
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
<span class="header-title-pre">{{ . | safeHTML }}</span>
|
||||
{{- end -}}
|
||||
{{- if .typeit -}}
|
||||
{{- $id := dict "Content" .name "Scratch" $.Scratch "Id" "typeit-header-desktop" | partial "function/id.html" -}}
|
||||
<span id="{{ $id }}" class="typeit"></span>
|
||||
{{- dict $id (slice $id) | dict "typeitMap" | merge ($.Scratch.Get "this") | $.Scratch.Set "this" -}}
|
||||
{{- $.Store.Set "hasTyped" true -}}
|
||||
<span class="typeit"><template>{{ .name | default $.Site.Title }}</template></span>
|
||||
{{- else -}}
|
||||
<span class="header-title-text">{{ .name | default $.Site.Title }}</span>
|
||||
{{- end -}}
|
||||
@@ -29,9 +28,8 @@
|
||||
</a>
|
||||
{{- with .Site.Params.header.subtitle -}}
|
||||
{{- if .typeit -}}
|
||||
{{- $id := dict "Content" .name "Scratch" $.Scratch "Id" "typeit-header-subtitle-desktop" | partial "function/id.html" -}}
|
||||
<span id="{{ $id }}" class="typeit header-subtitle"></span>
|
||||
{{- dict $id (slice $id) | dict "typeitMap" | merge ($.Scratch.Get "this") | $.Scratch.Set "this" -}}
|
||||
{{- $.Store.Set "hasTyped" true -}}
|
||||
<span class="typeit header-subtitle"><template>{{ .name }}</template></span>
|
||||
{{- else -}}
|
||||
<span class="header-subtitle">{{ .name }}</span>
|
||||
{{- end -}}
|
||||
@@ -125,7 +123,7 @@
|
||||
</li>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- else if gt (len .AllTranslations) 1 -}}
|
||||
{{- else if .IsTranslated -}}
|
||||
{{- range .AllTranslations -}}
|
||||
{{- if ne .Lang $.Lang -}}
|
||||
<li class="menu-item">
|
||||
@@ -164,9 +162,8 @@
|
||||
<span class="header-title-pre">{{ . | safeHTML }}</span>
|
||||
{{- end -}}
|
||||
{{- if .typeit -}}
|
||||
{{- $id := dict "Content" .name "Scratch" $.Scratch "Id" "typeit-header-title-mobile" | partial "function/id.html" -}}
|
||||
<span id="{{ $id }}" class="typeit"></span>
|
||||
{{- dict $id (slice $id) | dict "typeitMap" | merge ($.Scratch.Get "this") | $.Scratch.Set "this" -}}
|
||||
{{- $.Store.Set "hasTyped" true -}}
|
||||
<span class="typeit"><template>{{ .name | default $.Site.Title }}</template></span>
|
||||
{{- else -}}
|
||||
<span class="header-title-text">{{ .name | default $.Site.Title }}</span>
|
||||
{{- end -}}
|
||||
@@ -179,9 +176,8 @@
|
||||
</a>
|
||||
{{- with .Site.Params.header.subtitle -}}
|
||||
{{- if .typeit -}}
|
||||
{{- $id := dict "Content" .name "Scratch" $.Scratch "Id" "typeit-header-subtitle-mobile" | partial "function/id.html" -}}
|
||||
<span id="{{ $id }}" class="typeit header-subtitle"></span>
|
||||
{{- dict $id (slice $id) | dict "typeitMap" | merge ($.Scratch.Get "this") | $.Scratch.Set "this" -}}
|
||||
{{- $.Store.Set "hasTyped" true -}}
|
||||
<span class="typeit header-subtitle"><template>{{ .name }}</template></span>
|
||||
{{- else -}}
|
||||
<span class="header-subtitle">{{- .name -}}</span>
|
||||
{{- end -}}
|
||||
|
||||
@@ -45,10 +45,9 @@
|
||||
{{- with $profile.subtitle -}}
|
||||
<p class="home-subtitle">
|
||||
{{- if $profile.typeit -}}
|
||||
{{- $id := dict "Content" . "Scratch" $.Scratch "Id" "typeit-profile-subtitle" | partial "function/id.html" -}}
|
||||
<span class="d-none">{{ . }}</span>
|
||||
<span id="{{ $id }}" class="typeit"></span>
|
||||
{{- dict $id (slice $id) | dict "typeitMap" | merge ($.Scratch.Get "this") | $.Scratch.Set "this" -}}
|
||||
{{- $.Store.Set "hasTyped" true -}}
|
||||
<span class="typeit"><template>{{ . }}</template></span>
|
||||
{{- else -}}
|
||||
{{- . -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{{- /* FixIt theme environment detection */ -}}
|
||||
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
|
||||
{{- if hugo.IsProduction -}}
|
||||
{{- $cdn := .Site.Params.cdn -}}
|
||||
|
||||
@@ -4,12 +4,9 @@
|
||||
|
||||
{{- /* Check for updates */ -}}
|
||||
{{- if $devOpts.c4u -}}
|
||||
{{- /* Select the scope named "public_repo" to generate personal access token */ -}}
|
||||
{{- $header := dict "Authorization" "" -}}
|
||||
{{- with $devOpts.githubtoken -}}
|
||||
{{- $header = dict "Authorization" (printf "token %v" .) -}}
|
||||
{{- end -}}
|
||||
{{- $latest = (getJSON "https://api.github.com/repos/hugo-fixit/FixIt/releases/latest" $header).tag_name -}}
|
||||
{{- $url := "https://api.github.com/repos/hugo-fixit/FixIt/releases/latest" -}}
|
||||
{{- $options := dict "headers" (.Scratch.Get "githubTokenHeader") -}}
|
||||
{{- $latest = (partial "function/get-remote-json" (dict "URL" $url "OPTIONS" $options )).tag_name -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* FixIt theme version detection */ -}}
|
||||
|
||||
@@ -10,3 +10,14 @@
|
||||
{{- $homeRelPermalink = strings.TrimSuffix "archives/" $homeRelPermalink -}}
|
||||
{{- $homeRelPermalink = strings.TrimSuffix "offline/" $homeRelPermalink -}}
|
||||
{{- .Scratch.Set "homeRelPermalink" $homeRelPermalink -}}
|
||||
|
||||
{{- /* Set pages of main section */ -}}
|
||||
{{- $pages := where .Site.RegularPages "Type" "posts" -}}
|
||||
{{- .Scratch.Set "mainSectionPages" $pages -}}
|
||||
|
||||
{{- /* Select the scope named "public_repo" to generate personal access token */ -}}
|
||||
{{- $header := dict "Authorization" "" -}}
|
||||
{{- with .Site.Params.dev.githubtoken -}}
|
||||
{{- $header = dict "Authorization" (printf "token %v" .) -}}
|
||||
{{- end -}}
|
||||
{{- .Scratch.Set "githubTokenHeader" $header -}}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{{- .Scratch.Set "version" "v0.3.0" -}}
|
||||
{{- .Scratch.Set "params" (.Params | merge .Site.Params.page) -}}
|
||||
{{- .Scratch.Set "version" "v0.3.4" -}}
|
||||
{{- .Scratch.Set "this" dict -}}
|
||||
|
||||
{{- partial "init/detection-env.html" . -}}
|
||||
|
||||
@@ -1,35 +1,5 @@
|
||||
{{- /* FixIt theme patches */ -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
|
||||
{{- /* Author data patch */ -}}
|
||||
{{- $authorDefault := dict "name" "Anonymous" "link" "" "email" "" "avatar" "" -}}
|
||||
{{- $author := .Site.Params.author | merge $authorDefault -}}
|
||||
{{- $authorPost := dict -}}
|
||||
{{- $gravatar := .Site.Params.gravatar -}}
|
||||
{{- if reflect.IsMap $params.author -}}
|
||||
{{- $authorPost = $params.author -}}
|
||||
{{- else if isset $params "author" -}}
|
||||
{{- $authorPost = dict "name" $params.author -}}
|
||||
{{- end -}}
|
||||
{{- if isset $authorPost "name" | and (ne $authorPost.name .Site.Params.author.name) -}}
|
||||
{{- $author = $authorPost | merge $authorDefault | merge $author -}}
|
||||
{{- else -}}
|
||||
{{- with $authorPost.link -}}{{ $author = dict "link" . | merge $author }}{{- end -}}
|
||||
{{- with $authorPost.email -}}{{ $author = dict "email" . | merge $author }}{{- end -}}
|
||||
{{- with $authorPost.avatar -}}{{ $author = dict "avatar" . | merge $author }}{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $gravatar.enable | and $author.email -}}
|
||||
{{- with $gravatar -}}
|
||||
{{- $author = dict "avatar" (printf "https://%v/avatar/%v?s=32&d=%v"
|
||||
(path.Clean .Host | default "www.gravatar.com")
|
||||
(md5 $author.email)
|
||||
(.Style | default ""))
|
||||
| merge $author
|
||||
-}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- .Scratch.Set "author" $author -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
|
||||
{{- /* Toc data patch */ -}}
|
||||
{{- $toc := $params.toc -}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- $params := page.Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- $class := .Class | default "" -}}
|
||||
{{- $style := "" -}}
|
||||
{{- $loading := .Loading | default "lazy" -}}
|
||||
@@ -88,7 +88,7 @@
|
||||
<a class="lightgallery" href="{{ $srcLarge | safeURL }}" data-thumbnail="{{ $srcSmall | safeURL }}"{{ with $caption }} data-sub-html="<h2>{{ . }}</h2>{{ with $.Title }}<p>{{ . }}</p>{{ end }}"{{ end }}{{ with .Rel }} rel="{{ . }}"{{ end }}>
|
||||
{{- end -}}
|
||||
<img loading="{{ $loading }}" src="{{ $src | safeURL }}" alt="{{ $alt }}"
|
||||
{{- if .Responsive }} srcset="{{ $srcSmall | safeURL }}, {{ $srcMedium | safeURL }} 1.5x, {{ $srcLarge | safeURL }} 2x" sizes="auto"{{- end -}}
|
||||
{{- if .Responsive }} srcset="{{ $srcSmall | safeURL }}, {{ $srcMedium | safeURL }} 1.5x, {{ $srcLarge | safeURL }} 2x"{{- end -}}
|
||||
{{- if eq $loading "lazy" }} data-title="{{ .Title | default $alt }}"
|
||||
{{- else }} title="{{ .Title | default $alt }}"{{- end -}}
|
||||
{{- with .Width }} width="{{ . }}"{{- end -}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{{- $reward := .Reward -}}
|
||||
{{- $id := .Id -}}
|
||||
{{- $author := .Author -}}
|
||||
{{- $author := .Author | default "" -}}
|
||||
|
||||
{{- if $reward.enable -}}
|
||||
<div class="post-reward">
|
||||
@@ -12,7 +12,11 @@
|
||||
{{- with T (printf "single.reward.%v" $way) -}}{{ $way = . }}{{- end -}}
|
||||
{{- if $image -}}
|
||||
<div>
|
||||
{{- dict "Src" $image "Alt" (printf "%v %v" $author $way) | partial "plugin/image.html" -}}
|
||||
{{-
|
||||
dict "Src" $image
|
||||
"Alt" (strings.TrimPrefix " " (printf "%v %v" $author $way))
|
||||
| partial "plugin/image.html"
|
||||
-}}
|
||||
<span{{ if $reward.animation }} data-animation{{ end }}>{{ $way }}</span>
|
||||
</div>
|
||||
{{- end -}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- $share := (.Scratch.Get "params").share | default dict -}}
|
||||
{{- $share := (partial "function/params.html").share | default dict -}}
|
||||
|
||||
{{- if $share.enable -}}
|
||||
{{- /* 001: Twitter */ -}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{- /* Collection List */ -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
|
||||
{{- if .Params.collections | and $params.collectionList | and (not $params.password) -}}
|
||||
{{- $collectionTerms := .GetTerms "collections" -}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{- /* Collection Navigation */ -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
|
||||
{{- if .Params.collections | and $params.collectionNavigation | and (not $params.password) -}}
|
||||
{{- $collectionTerms := .GetTerms "collections" -}}
|
||||
|
||||
@@ -15,18 +15,22 @@
|
||||
{{- $artalk := $comment.artalk | default dict -}}
|
||||
{{- if $artalk.enable -}}
|
||||
<div id="artalk" class="comment"></div>
|
||||
{{- $source := $cdn.artalkCSS | default "lib/artalk/Artalk.css" -}}
|
||||
{{- $source := $cdn.artalkCSS | default (add $artalk.server "/dist/Artalk.css") -}}
|
||||
{{- dict "Source" $source "Minify" true "Fingerprint" $fingerprint | dict "Scratch" .Scratch "Data" | partial "scratch/style.html" -}}
|
||||
{{- $source := $cdn.artalkJS | default "lib/artalk/Artalk.js" -}}
|
||||
{{- $source := $cdn.artalkJS | default (add $artalk.server "/dist/Artalk.js") -}}
|
||||
{{- dict "Source" $source "Fingerprint" $fingerprint | dict "Scratch" .Scratch "Data" | partial "scratch/script.html" -}}
|
||||
{{- $commentConfig = dict "el" "#artalk" "pageKey" .Permalink "pageTitle" .Title "pvEl" "artalk-visitor-count" "countEl" "artalk-comment-count" | dict "artalk" | merge $commentConfig -}}
|
||||
{{- if (eq $artalk.locale "") | and (eq $.Site.LanguageCode "en") -}}
|
||||
{{- $artalk = dict "locale" "en-US" | merge $artalk -}}
|
||||
{{- end -}}
|
||||
{{- $commentConfig = dict "locale" ($artalk.locale | default $.Site.LanguageCode | default "auto") | dict "artalk" | merge $commentConfig -}}
|
||||
{{- if eq $artalk.usebackendconf false -}}
|
||||
{{- $commentConfig = dict "useBackendConf" false | dict "artalk" | merge $commentConfig -}}
|
||||
{{- end -}}
|
||||
{{- with .Site.Params.gravatar -}}
|
||||
{{/* See https://artalk.js.org/guide/frontend/config.html#gravatar-params */}}
|
||||
{{- $commentConfig = dict "mirror" .Host "params" (printf "d=%v&s=240" .Style) | dict "gravatar" | dict "artalk" | merge $commentConfig -}}
|
||||
{{- $gravatarMirror := printf "https://%v/avatar/" .Host -}}
|
||||
{{- $commentConfig = dict "mirror" $gravatarMirror "params" (printf "d=%v&s=240" .Style) | dict "gravatar" | dict "artalk" | merge $commentConfig -}}
|
||||
{{- end -}}
|
||||
{{- with $artalk.server -}}
|
||||
{{- $commentConfig = dict "server" . | dict "artalk" | merge $commentConfig -}}
|
||||
@@ -297,7 +301,7 @@
|
||||
{{- with $giscus -}}
|
||||
{{- $commentConfig = .lightTheme | default "light" | dict "lightTheme" | dict "giscus" | merge $commentConfig -}}
|
||||
{{- $commentConfig = .darkTheme | default "dark" | dict "darkTheme" | dict "giscus" | merge $commentConfig -}}
|
||||
<div id="giscus">
|
||||
<div id="giscus" class="comment">
|
||||
<script
|
||||
src="https://giscus.app/client.js"
|
||||
data-repo="{{ .Repo }}"
|
||||
@@ -325,7 +329,7 @@
|
||||
{{- end -}}
|
||||
</div>
|
||||
{{- /* lightgallery for Artalk and Twikoo */ -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- if not $params.lightgallery | and (($artalk.enable | and $artalk.lightgallery) | or ($twikoo.enable | and $twikoo.lightgallery)) -}}
|
||||
{{- $source := $cdn.lightgalleryCSS | default "lib/lightgallery/css/lightgallery-bundle.min.css" -}}
|
||||
{{- dict "Source" $source "Fingerprint" $fingerprint | dict "Scratch" .Scratch "Data" | partial "scratch/style.html" -}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- $expirationReminder := $params.expirationReminder | default dict -}}
|
||||
|
||||
{{- if $expirationReminder.enable -}}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
|
||||
{{- if $params.password -}}
|
||||
{{- $msg := (.Scratch.Get "params").message | default (T "single.encryptedMessage") -}}
|
||||
{{- $msg := $params.message | default (T "single.encryptedMessage") -}}
|
||||
{{- $loading := resources.Get "images/loading.svg" | minify -}}
|
||||
<div class="fixit-decryptor-container">
|
||||
<img class="fixit-decryptor-loading" src="{{ $loading.RelPermalink }}" alt="decryptor loading" />
|
||||
<label for="fixit-decryptor-input" title='{{ T "single.password" }}'>
|
||||
<input type="password" id="fixit-decryptor-input" class="d-none" placeholder="🔑 {{ $msg }}" />
|
||||
<input type="password" id="fixit-decryptor-input" class="fixit-decryptor-input d-none" placeholder="🔑 {{ $msg }}" />
|
||||
</label>
|
||||
<button class="fixit-decryptor-btn d-none">
|
||||
{{- dict "Class" "fa-solid fa-unlock" | partial "plugin/icon.html" }} {{ T "single.enterBtn" -}}
|
||||
</button>
|
||||
<button class="fixit-encryptor-btn d-none">
|
||||
{{- dict "Class" "fa-solid fa-lock" | partial "plugin/icon.html" }} {{ T "single.encryptyAgain" -}}
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
|
||||
{{- /* Git info */ -}}
|
||||
{{- $gitRepo := "" -}}
|
||||
@@ -98,8 +98,13 @@
|
||||
</div>
|
||||
|
||||
<div class="post-nav">
|
||||
{{- $prev := cond .Site.Params.navigationReverse .Next .Prev -}}
|
||||
{{- $next := cond .Site.Params.navigationReverse .Prev .Next -}}
|
||||
{{- $pages := .Scratch.Get "mainSectionPages" -}}
|
||||
{{- $prev := $pages.Prev . -}}
|
||||
{{- $next := $pages.Next . -}}
|
||||
{{- if .Site.Params.navigationReverse -}}
|
||||
{{- $prev = $pages.Next . -}}
|
||||
{{- $next = $pages.Prev . -}}
|
||||
{{- end -}}
|
||||
{{- with $prev -}}
|
||||
<a href="{{ .RelPermalink }}" class="post-nav-item" rel="prev" title="{{ .LinkTitle }}">
|
||||
{{- dict "Class" "fa-solid fa-angle-left fa-fw" | partial "plugin/icon.html" -}}
|
||||
|
||||
@@ -1,11 +1,41 @@
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $author := .Scratch.Get "author" -}}
|
||||
{{- $params := .Params | merge .Site.Params.page -}}
|
||||
|
||||
{{- /* Author data patch */ -}}
|
||||
{{- $authorDefault := dict "name" "" "link" "" "email" "" "avatar" "" -}}
|
||||
{{- $author := .Site.Params.author | merge $authorDefault -}}
|
||||
{{- $authorPost := dict -}}
|
||||
{{- if reflect.IsMap $params.author -}}
|
||||
{{- $authorPost = $params.author -}}
|
||||
{{- else if isset $params "author" -}}
|
||||
{{- warnf "检测到你的 author 参数格式错误,请参考主题文档设置为正常的格式。" -}}
|
||||
{{- $authorPost = dict "name" $params.author -}}
|
||||
{{- end -}}
|
||||
{{- if isset $authorPost "name" | and (ne $authorPost.name .Site.Params.author.name) -}}
|
||||
{{- $author = $authorPost | merge $authorDefault | merge $author -}}
|
||||
{{- else -}}
|
||||
{{- with $authorPost.link -}}{{ $author = dict "link" . | merge $author }}{{- end -}}
|
||||
{{- with $authorPost.email -}}{{ $author = dict "email" . | merge $author }}{{- end -}}
|
||||
{{- with $authorPost.avatar -}}{{ $author = dict "avatar" . | merge $author }}{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $gravatar := .Site.Params.gravatar -}}
|
||||
{{- if $gravatar.enable | and $author.email -}}
|
||||
{{- with $gravatar -}}
|
||||
{{- $author = dict "avatar" (printf "https://%v/avatar/%v?s=32&d=%v"
|
||||
(path.Clean .Host | default "www.gravatar.com")
|
||||
(md5 $author.email)
|
||||
(.Style | default ""))
|
||||
| merge $author
|
||||
-}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- .Store.Set "author" $author -}}
|
||||
|
||||
<span class="post-author">
|
||||
{{- $content := $author.name -}}
|
||||
{{- $content := $author.name | default "Anonymous" -}}
|
||||
{{- $icon := dict "Class" "fa-solid fa-user-circle" -}}
|
||||
{{- if $author.avatar | and $params.authorAvatar -}}
|
||||
{{- $content = printf "%v %v" (dict "Src" $author.avatar "Class" "avatar" "Alt" $author.name | partial "plugin/image.html") $author.name -}}
|
||||
{{- $content = printf "%v %v" (dict "Src" $author.avatar "Class" "avatar" "Alt" $content | partial "plugin/image.html") $content -}}
|
||||
{{- $icon = "" -}}
|
||||
{{- end -}}
|
||||
{{- if $author.link -}}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{{- /* Related Content */ -}}
|
||||
{{- /* https://gohugo.io/content-management/related/ */ -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
|
||||
{{- if $params.related.enable | and (not $params.password) -}}
|
||||
{{- $posts := where .Site.RegularPages "Type" "posts" -}}
|
||||
{{- $posts := .Scratch.Get "mainSectionPages" -}}
|
||||
{{- if .Site.Params.page.hiddenFromRelated -}}
|
||||
{{- $posts = where $posts "Params.hiddenfromrelated" false -}}
|
||||
{{- else -}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- $reward := .Scratch.Get "reward" -}}
|
||||
{{- $author := .Scratch.Get "author" -}}
|
||||
{{- $author := .Store.Get "author" -}}
|
||||
{{- $options := dict "Reward" $reward "Id" "fi-reward" "Author" $author.name -}}
|
||||
{{- partial "plugin/reward.html" $options -}}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{{- end -}}
|
||||
|
||||
{{- define "content" -}}
|
||||
{{- $params := .Scratch.Get "params" -}}
|
||||
{{- $params := partial "function/params.html" -}}
|
||||
{{- $toc := .Scratch.Get "toc" -}}
|
||||
{{- $tocEmpty := eq .TableOfContents `<nav id="TableOfContents"></nav>` -}}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{{- $content := .Inner | transform.Unmarshal | jsonify -}}
|
||||
{{- $id := dict "Content" $content "Scratch" .Page.Scratch | partial "function/id.html" -}}
|
||||
{{- $width := cond .IsNamedParams (.Get "width") (.Get 0) | default "100%" -}}
|
||||
{{- $height := cond .IsNamedParams (.Get "height") (.Get 1) | default "30rem" -}}
|
||||
<div class="echarts" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
|
||||
{{- .Page.Scratch.SetInMap "this" "echarts" true -}}
|
||||
{{- $attrs := printf `style="width: %v; height: %v;"` $width $height -}}
|
||||
<div class="echarts" {{ $attrs | safeHTMLAttr }}></div>
|
||||
<template>{{ $content }}</template>
|
||||
{{- /* EOF */ -}}
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
<label title='{{ T "single.password" }}'>
|
||||
<input type="password" class="fixit-decryptor-input" placeholder="🔑 {{ $message }}" />
|
||||
</label>
|
||||
<button class="fixit-decryptor-btn">
|
||||
{{- dict "Class" "fa-solid fa-unlock" | partial "plugin/icon.html" }} {{ T "single.enterBtn" -}}
|
||||
</button>
|
||||
</div>
|
||||
<div data-password="{{ md5 $password }}" data-content="{{ $content }}"></div>
|
||||
</fixit-encryptor>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{{- $mapbox := (.Page.Scratch.Get "params").mapbox | default dict -}}
|
||||
{{- $mapbox := (partial "function/params.html").mapbox | default dict -}}
|
||||
|
||||
{{- $lng := cond .IsNamedParams (.Get "lng") (.Get 0) -}}
|
||||
{{- $lat := cond .IsNamedParams (.Get "lat") (.Get 1) -}}
|
||||
@@ -28,6 +28,7 @@
|
||||
{{- end -}}
|
||||
{{- $darkStyle = $darkStyle | default $lightStyle -}}
|
||||
{{- $options := dict "lng" $lng "lat" $lat "zoom" $zoom "marked" $marked "lightStyle" $lightStyle "darkStyle" $darkStyle "geolocate" $geolocate "navigation" $navigation "scale" $scale "fullscreen" $fullscreen -}}
|
||||
{{- $id := dict "Content" $options "Scratch" .Page.Scratch | partial "function/id.html" -}}
|
||||
<div class="mapbox" id="{{ $id }}" style="width: {{ $width }}; height: {{ $height }};"></div>
|
||||
{{- .Page.Scratch.SetInMap "this" "mapbox" true -}}
|
||||
|
||||
{{- $attrs := printf `style="width: %v; height: %v;"` $width $height -}}
|
||||
<div class="mapbox" data-options="{{ $options | jsonify }}" {{ $attrs | safeHTMLAttr }}></div>
|
||||
{{- /* EOF */ -}}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
{{- $id := dict "Content" (trim (partial "function/dos2unix.html" .Inner) "\n") "Scratch" .Page.Scratch | partial "function/id.html" -}}
|
||||
<div class="mermaid" id="{{ $id }}"></div>
|
||||
{{- .Page.Scratch.SetInMap "this" "mermaid" true -}}
|
||||
<pre class="mermaid">
|
||||
{{- .Inner | safeHTML }}
|
||||
</pre>
|
||||
<template>{{- .Inner | safeHTML }}</template>
|
||||
{{- .Page.Store.Set "hasMermaid" true -}}
|
||||
|
||||
@@ -47,4 +47,3 @@
|
||||
{{- else -}}
|
||||
<meting-js server="{{ .Get 0 }}" type="{{ .Get 1 }}" id="{{ .Get 2 }}" theme="{{ $theme }}"></meting-js>
|
||||
{{- end -}}
|
||||
{{- .Page.Scratch.SetInMap "this" "music" true -}}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{{- $alipay := (.Get "alipay") | default (.Get 1) -}}
|
||||
{{- $paypal := (.Get "paypal") | default (.Get 2) -}}
|
||||
{{- $bitcoin := (.Get "bitcoin") | default (.Get 3) -}}
|
||||
{{- $author := (.Get "author") | default (.Get 4) | default (.Page.Scratch.Get "author").name -}}
|
||||
{{- $author := (.Get "author") | default (.Get 4) -}}
|
||||
{{- $comment := (.Get "comment") | default (.Get 5) -}}
|
||||
{{- $mode := (.Get "mode") | default (.Get 6) -}}
|
||||
{{- $reward := dict "enable" true "comment" $comment "mode" $mode -}}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{{- /* trim the newline */ -}}
|
||||
{{- $content := trim (partial "function/dos2unix.html" .Inner) "\n" -}}
|
||||
{{- $classList := slice -}}
|
||||
{{- with .Get "class" -}}
|
||||
@@ -15,25 +16,26 @@
|
||||
{{- /* parsing code links */ -}}
|
||||
{{- $content = replaceRE `(<span[^<>]*>)([^<>]*)\[([^<>]+)\]\(([^<>]+)\)([^<>]*)(</span>)` "$1$2$6<a href=\"$4\">$3</a>$1$5$6" $content -}}
|
||||
{{- end -}}
|
||||
{{- /* split multiline string */ -}}
|
||||
{{- $content = split $content "\n" -}}
|
||||
{{- $classList = $classList | append "highlight" -}}
|
||||
{{- else -}}
|
||||
{{- $content = $content | .Page.RenderString -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* trim the newline */ -}}
|
||||
{{- $id := dict "Content" $content "Scratch" .Page.Scratch | partial "function/id.html" -}}
|
||||
{{- $key := .Get "group" | string | default $id -}}
|
||||
{{- $typeitMap := (.Page.Scratch.Get "this").typeitMap | default dict -}}
|
||||
{{- $group := index $typeitMap $key -}}
|
||||
{{- $group = $group | default slice | append $id -}}
|
||||
{{- dict $key $group | merge $typeitMap | .Page.Scratch.SetInMap "this" "typeitMap" -}}
|
||||
|
||||
{{- $attrs := printf `id="%v"` $id -}}
|
||||
{{- with $classList -}}
|
||||
{{- $attrs = delimit $classList " " | printf `%v class="%v"` $attrs -}}
|
||||
{{- $wrapperAttrs := `class="typeit"` -}}
|
||||
{{- with (.Get "group" | string) -}}
|
||||
{{- $wrapperAttrs = printf `%v data-group="%v"` $wrapperAttrs . -}}
|
||||
{{- end -}}
|
||||
{{- with $loop -}}
|
||||
{{- $wrapperAttrs = printf `%v data-loop="true"` $wrapperAttrs -}}
|
||||
{{- end -}}
|
||||
|
||||
<div class="typeit"{{ if ne $loop "" }} data-loop="{{ $loop }}"{{ end }}>{{ printf `<%v %v></%v>` $tag $attrs $tag | safeHTML }}</div>
|
||||
{{- /* EOF */ -}}
|
||||
{{- $innerAttrs := "" -}}
|
||||
{{- with $classList -}}
|
||||
{{- $innerAttrs = printf `class="%v"` (delimit $classList " ") -}}
|
||||
{{- end -}}
|
||||
|
||||
<div {{ $wrapperAttrs | safeHTMLAttr }}>
|
||||
{{- printf `<%v %v></%v>` $tag $innerAttrs $tag | safeHTML -}}
|
||||
<template><pre>{{ printf "%v" $content | safeHTML }}</pre></template>
|
||||
</div>
|
||||
{{- .Page.Store.Set "hasTyped" true -}}
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
{{- else -}}
|
||||
{{- $termTitle = printf "%v - %v" (T $taxonomy | default $taxonomy) .Title -}}
|
||||
{{- end -}}
|
||||
<h2 class="single-title animate__animated animate__pulse animate__faster">
|
||||
<h1 class="single-title animate__animated animate__pulse animate__faster">
|
||||
{{- with $termIcon -}}
|
||||
{{- dict "Class" (add . " fa-fw me-1") | partial "plugin/icon.html" -}}
|
||||
{{- end -}}
|
||||
{{- $termTitle }} <sup>{{ $pageCount }}</sup>
|
||||
</h2>
|
||||
</h1>
|
||||
|
||||
{{- /* Paginate */ -}}
|
||||
{{- if .Pages -}}
|
||||
@@ -35,7 +35,10 @@
|
||||
{{- $pages = .Paginate $pages -}}
|
||||
{{- end -}}
|
||||
{{- range $pages.PageGroups -}}
|
||||
<h3 class="group-title">{{ .Key }}</h3>
|
||||
<h2 class="group-title">
|
||||
{{- dict "Class" "fa-regular fa-calendar fa-fw me-1" | partial "plugin/icon.html" -}}
|
||||
{{- .Key -}}
|
||||
</h2>
|
||||
{{- range .Pages -}}
|
||||
<article class="archive-item">
|
||||
<a href="{{ .RelPermalink }}" class="archive-item-link">
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
{{- $termsIcon = "fa-solid fa-layer-group" -}}
|
||||
{{- end -}}
|
||||
{{- /* Title */ -}}
|
||||
<h2 class="single-title animate__animated animate__pulse animate__faster">
|
||||
<h1 class="single-title animate__animated animate__pulse animate__faster">
|
||||
{{- with $termsIcon -}}
|
||||
{{- dict "Class" (add . " fa-fw me-1") | partial "plugin/icon.html" -}}
|
||||
{{- end -}}
|
||||
{{- .Params.Title | default (T $taxonomies) | default $taxonomies | dict "Some" | T "allSome" }} <sup>{{ len .Data.Terms.ByCount }}</sup>
|
||||
</h2>
|
||||
</h1>
|
||||
{{- /* Render miscellaneous terms */ -}}
|
||||
{{- .Render (add "terms/" $taxonomies) -}}
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user