mirror of
https://github.com/cotes2020/jekyll-theme-chirpy.git
synced 2025-12-18 13:44:15 +00:00
Compare commits
391 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b5a3865ac | ||
|
|
fe2a3cdf51 | ||
|
|
4e7bf00ee9 | ||
|
|
773d3b1263 | ||
|
|
b0d5956f5a | ||
|
|
e50343b06b | ||
|
|
b3de722778 | ||
|
|
782a930fdf | ||
|
|
da7d7e25b6 | ||
|
|
f6e9a3fccf | ||
|
|
ae2669fedc | ||
|
|
48f14e39ac | ||
|
|
6774e0e1fb | ||
|
|
8134209aa2 | ||
|
|
c0e3e61fa7 | ||
|
|
e107a2e759 | ||
|
|
df8185f887 | ||
|
|
339293d0d7 | ||
|
|
1fd665bf49 | ||
|
|
e48d66e525 | ||
|
|
647eea8dbd | ||
|
|
1c330f403c | ||
|
|
b6a1a4172e | ||
|
|
3c44a1ff71 | ||
|
|
e7dee2a589 | ||
|
|
a6ce765082 | ||
|
|
294e2985c1 | ||
|
|
5de6f17754 | ||
|
|
d96fa5aa0c | ||
|
|
6852ceb280 | ||
|
|
f904e8cd48 | ||
|
|
81b9f7a9ac | ||
|
|
916fbf4a2c | ||
|
|
d9d7848f03 | ||
|
|
70662a0365 | ||
|
|
3432413020 | ||
|
|
fd5df7e1a1 | ||
|
|
65f722fb04 | ||
|
|
1082d041ca | ||
|
|
eac3f9b434 | ||
|
|
304d75c500 | ||
|
|
fb13e3219b | ||
|
|
5511b2883f | ||
|
|
76712c09cd | ||
|
|
80cb0b3717 | ||
|
|
d2fb98b3e5 | ||
|
|
39da11e3f3 | ||
|
|
fec5214b45 | ||
|
|
827f84c7e8 | ||
|
|
3ffd19d81d | ||
|
|
49bb93cc0c | ||
|
|
8bcdd87891 | ||
|
|
7cc36c5287 | ||
|
|
3878815852 | ||
|
|
e55ebadeb2 | ||
|
|
0c5b697fd3 | ||
|
|
f1d9e99bc0 | ||
|
|
b288587c1c | ||
|
|
f35b147b28 | ||
|
|
163c5761e9 | ||
|
|
4023be9bef | ||
|
|
0dcd39d491 | ||
|
|
45c58d8f4c | ||
|
|
e993ac872a | ||
|
|
21c8c2b70d | ||
|
|
43323abdfe | ||
|
|
b78a2d85bd | ||
|
|
940b2810e9 | ||
|
|
b405a58838 | ||
|
|
d792a2f6af | ||
|
|
22d4275f75 | ||
|
|
3fa1bf3054 | ||
|
|
ad137fa294 | ||
|
|
20b7fe3a53 | ||
|
|
5eb329f36c | ||
|
|
378b65a061 | ||
|
|
2fed338ce6 | ||
|
|
232927c47c | ||
|
|
5b97d3fd25 | ||
|
|
856ef11487 | ||
|
|
b0329775fc | ||
|
|
971fe03ec3 | ||
|
|
96af7291ea | ||
|
|
4c45f3788e | ||
|
|
baad801066 | ||
|
|
7f18cdc1fd | ||
|
|
fd0f983bbe | ||
|
|
35cadf969d | ||
|
|
cc6398c104 | ||
|
|
5d6e8c5ef6 | ||
|
|
20caace68a | ||
|
|
ac1731d123 | ||
|
|
106c981bac | ||
|
|
d127183b97 | ||
|
|
54124d5134 | ||
|
|
76a1b6a068 | ||
|
|
91308ae567 | ||
|
|
12f1e6fe89 | ||
|
|
94e81447af | ||
|
|
b7ad538ce2 | ||
|
|
097bb23530 | ||
|
|
2bd6efa95a | ||
|
|
135a16f13e | ||
|
|
6d35f5f8da | ||
|
|
42c44a8bc1 | ||
|
|
138c537010 | ||
|
|
59e955745f | ||
|
|
4f590e2bba | ||
|
|
6900d9f2bc | ||
|
|
30787fc4cf | ||
|
|
5402523ae5 | ||
|
|
156c02a91a | ||
|
|
6ca66366d5 | ||
|
|
0740b857c6 | ||
|
|
58928dbc90 | ||
|
|
0542b5149c | ||
|
|
e68108014a | ||
|
|
efe75adf27 | ||
|
|
3e64400246 | ||
|
|
f581b4395f | ||
|
|
96a16c868e | ||
|
|
67d51d5df2 | ||
|
|
9cefe58993 | ||
|
|
b8d1bcd3de | ||
|
|
a60a4562bf | ||
|
|
03e4f575ba | ||
|
|
b58cab1c07 | ||
|
|
da05d395fb | ||
|
|
f0a2e2f4e1 | ||
|
|
c57238975a | ||
|
|
c2c503f633 | ||
|
|
5607a1755a | ||
|
|
5a575613bb | ||
|
|
00ad357033 | ||
|
|
dd9d5a7207 | ||
|
|
d2bbcb791f | ||
|
|
4c1c8d8b0e | ||
|
|
2103191b2f | ||
|
|
5d85ccb994 | ||
|
|
7fef3fafec | ||
|
|
887859dd32 | ||
|
|
42fe8f5d21 | ||
|
|
171463d76d | ||
|
|
dd264e793c | ||
|
|
004ab6c56a | ||
|
|
3969b28743 | ||
|
|
5f31fbcf72 | ||
|
|
4986db1204 | ||
|
|
508d3c5c6a | ||
|
|
35e013f7fd | ||
|
|
e52dc9551c | ||
|
|
5753118d8b | ||
|
|
5295bbf4f9 | ||
|
|
cfd05d1aa5 | ||
|
|
6c4d0e0def | ||
|
|
15cfa84ddb | ||
|
|
08a993be90 | ||
|
|
2b66ad0441 | ||
|
|
0f6b170e24 | ||
|
|
4df4f7f8db | ||
|
|
09f1ded60c | ||
|
|
70e089c392 | ||
|
|
dc42b6f800 | ||
|
|
3685685b28 | ||
|
|
51688ccc9f | ||
|
|
3db6de0abb | ||
|
|
b27258899b | ||
|
|
cfe9029cd1 | ||
|
|
2c5e67f02b | ||
|
|
7a392510e6 | ||
|
|
85fe258b20 | ||
|
|
55fd119d35 | ||
|
|
fc36f8b66d | ||
|
|
a5d38e7fbc | ||
|
|
a24545ed60 | ||
|
|
66e655f09b | ||
|
|
c3b2151ca0 | ||
|
|
3d8184602b | ||
|
|
c344926886 | ||
|
|
756465d621 | ||
|
|
7b0e9a6803 | ||
|
|
f043123f23 | ||
|
|
ca181422a6 | ||
|
|
4845f6ef14 | ||
|
|
031e878620 | ||
|
|
166c05bcd1 | ||
|
|
0890147423 | ||
|
|
323a888160 | ||
|
|
7788a140f2 | ||
|
|
1b379e3870 | ||
|
|
640bde95c4 | ||
|
|
1a93d5e557 | ||
|
|
b8c3ea221e | ||
|
|
4a2016a9e3 | ||
|
|
a6c73e8f4f | ||
|
|
f8f4dd889e | ||
|
|
96e7cd79af | ||
|
|
22c12a4d34 | ||
|
|
2cef631385 | ||
|
|
9620eddd12 | ||
|
|
dbf86a2309 | ||
|
|
2d02a6415d | ||
|
|
67bd6679b9 | ||
|
|
f2a2792405 | ||
|
|
837d0778b6 | ||
|
|
97ae2bf6c0 | ||
|
|
e7b377cf63 | ||
|
|
b0815b53c0 | ||
|
|
4dd0c6d16f | ||
|
|
57a76097d6 | ||
|
|
22e2367b45 | ||
|
|
b44bf78f10 | ||
|
|
948356d7d6 | ||
|
|
7337fa5f20 | ||
|
|
44acea2f5d | ||
|
|
65a38c8f22 | ||
|
|
b91b6711b0 | ||
|
|
aeb2d57b60 | ||
|
|
2406ce1dc8 | ||
|
|
bec9246823 | ||
|
|
adaefc02e9 | ||
|
|
ee7266ff0d | ||
|
|
cad62feb91 | ||
|
|
b85cb39388 | ||
|
|
4360e2938c | ||
|
|
ecf31ff308 | ||
|
|
37344ef0df | ||
|
|
9e2a4fc8c9 | ||
|
|
fc71289dc8 | ||
|
|
c8fd0d728d | ||
|
|
ef2aa525d5 | ||
|
|
1fe0b2958b | ||
|
|
e466a643d5 | ||
|
|
f7ec9cd24a | ||
|
|
3342abc9e6 | ||
|
|
d47ec035d3 | ||
|
|
a403ffee42 | ||
|
|
d315bf57e7 | ||
|
|
75176522e3 | ||
|
|
ebb3dc940c | ||
|
|
c02c9c6a04 | ||
|
|
3a4316b29b | ||
|
|
f4b2dfe8b4 | ||
|
|
09e8eb4274 | ||
|
|
5ca0966c41 | ||
|
|
d919f833f1 | ||
|
|
df81012e28 | ||
|
|
09742d40dd | ||
|
|
259d0deabc | ||
|
|
cf6c8e9b3a | ||
|
|
c64e587335 | ||
|
|
415f11ecb8 | ||
|
|
5dc830d11e | ||
|
|
7579644e8d | ||
|
|
4cff83268b | ||
|
|
1487ae5284 | ||
|
|
697c584b48 | ||
|
|
089a19bc9e | ||
|
|
007d242e87 | ||
|
|
6447ffaf59 | ||
|
|
790cf30376 | ||
|
|
45adf4aac2 | ||
|
|
b1377ac694 | ||
|
|
cf8dae9454 | ||
|
|
9f5e579596 | ||
|
|
99e468cae5 | ||
|
|
4fde37e879 | ||
|
|
19debc4add | ||
|
|
afcf0bde22 | ||
|
|
36f55f091d | ||
|
|
e2003f2b03 | ||
|
|
563e8085e8 | ||
|
|
902546cf4d | ||
|
|
e06d237eae | ||
|
|
6220d09ffb | ||
|
|
3c91dc1f6f | ||
|
|
6a65f3a7f7 | ||
|
|
57feaa660e | ||
|
|
db9cfc270b | ||
|
|
3caacbee61 | ||
|
|
b518c9d3bc | ||
|
|
1c758cf4a2 | ||
|
|
df3a703988 | ||
|
|
12407bbfc0 | ||
|
|
55fce7574c | ||
|
|
833b6c9d5c | ||
|
|
a34b77969f | ||
|
|
707466b1df | ||
|
|
602e98448d | ||
|
|
0bf7a8f1d9 | ||
|
|
a7361717a6 | ||
|
|
e880448ba5 | ||
|
|
c28b6ce7d1 | ||
|
|
b7cc22983f | ||
|
|
a1551cd740 | ||
|
|
35c4d480ed | ||
|
|
b5c26fed08 | ||
|
|
2dc2175723 | ||
|
|
2f79b8d408 | ||
|
|
cbe6c3fb7b | ||
|
|
bb1188a01a | ||
|
|
406ed520cb | ||
|
|
1d7a134dd5 | ||
|
|
421db9dc92 | ||
|
|
a5b8e7862b | ||
|
|
30d3249782 | ||
|
|
fa15aebbca | ||
|
|
565ad9229c | ||
|
|
3d6304efd8 | ||
|
|
80fd684577 | ||
|
|
80980465d7 | ||
|
|
2858a082a3 | ||
|
|
9b0b7d7772 | ||
|
|
952b1f493b | ||
|
|
a887f1d57d | ||
|
|
945e8d1953 | ||
|
|
a400dc9501 | ||
|
|
6a4169fc03 | ||
|
|
95b4b453e6 | ||
|
|
de14c00570 | ||
|
|
f4d4065b1c | ||
|
|
52f854a2da | ||
|
|
38f20e8119 | ||
|
|
1728d697e6 | ||
|
|
d9863d6a02 | ||
|
|
b460d03c3b | ||
|
|
a053c454e4 | ||
|
|
77c2009658 | ||
|
|
9844b964a8 | ||
|
|
063b2a6651 | ||
|
|
e5df04dd59 | ||
|
|
9e9278ce30 | ||
|
|
30dfc6fb7e | ||
|
|
1ce350e33e | ||
|
|
50c88f7205 | ||
|
|
387fc67102 | ||
|
|
414715fc47 | ||
|
|
1bb54096f4 | ||
|
|
abb548fcee | ||
|
|
ed93fbdfde | ||
|
|
4ad0a76789 | ||
|
|
89b76dc2a0 | ||
|
|
395b24736a | ||
|
|
fa0155de6f | ||
|
|
0bffb276fe | ||
|
|
2417db656c | ||
|
|
e5bf234835 | ||
|
|
2dfdb66e0a | ||
|
|
da9881a47f | ||
|
|
c68a937e01 | ||
|
|
4001ef7cba | ||
|
|
1b16b152df | ||
|
|
e607e5fe86 | ||
|
|
d761d340a8 | ||
|
|
f411ba33d8 | ||
|
|
f722757f6f | ||
|
|
beabb36d7f | ||
|
|
42ff0f2282 | ||
|
|
34631a0c30 | ||
|
|
53b0329e5a | ||
|
|
2877896b9e | ||
|
|
7ef88c8b8f | ||
|
|
2acf14ecf0 | ||
|
|
603705f20e | ||
|
|
0267ad8d40 | ||
|
|
c0b8c089c2 | ||
|
|
a603aac8e8 | ||
|
|
91ed3d4649 | ||
|
|
20454e5a57 | ||
|
|
aadda0347c | ||
|
|
5e9a7b319e | ||
|
|
2537283beb | ||
|
|
7dc7a7efc8 | ||
|
|
39b09b97c0 | ||
|
|
8d164c2e6e | ||
|
|
1a94b1889f | ||
|
|
6d07d4738b | ||
|
|
6e0afcf9e8 | ||
|
|
952927762a | ||
|
|
3c3598e8b1 | ||
|
|
9d9bca5e3b | ||
|
|
03248f5bff | ||
|
|
e2c288a925 | ||
|
|
b80d95dcdd | ||
|
|
72ba1f7849 | ||
|
|
46d80cbf9a | ||
|
|
0213331a16 | ||
|
|
780af9ac5f | ||
|
|
b513c0764d | ||
|
|
57e8c6e594 | ||
|
|
49dc866bd8 |
8
.commitlintrc.json
Normal file
8
.commitlintrc.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"rules": {
|
||||
"body-max-line-length": [
|
||||
0,
|
||||
"always"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,13 @@ root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
# 2 space indentation
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
# Unix-style newlines with a newline ending every file
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
|
||||
[*.js]
|
||||
indent_size = 4
|
||||
|
||||
2
.github/CODE_OF_CONDUCT.md
vendored
2
.github/CODE_OF_CONDUCT.md
vendored
@@ -70,4 +70,4 @@ available at <https://www.contributor-covenant.org/version/1/4/code-of-conduct.h
|
||||
For answers to common questions about this code of conduct, see
|
||||
<https://www.contributor-covenant.org/faq>
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
62
.github/CONTRIBUTING.md
vendored
62
.github/CONTRIBUTING.md
vendored
@@ -1,16 +1,66 @@
|
||||
# How to Contribute
|
||||
|
||||
I want to thank you for sparing a time to improve this project! Here are some guidelines for contributing:
|
||||
We'd like to thank you for sparing time to improve this project! Here are some guidelines for contributing:
|
||||
|
||||
To ensure that the blog design is not confused, this project does not accept suggestions for design changes, such as color scheme, fonts, typography, etc. If your request is about an enhancement, it is recommended to first submit a [`Feature Request`](https://github.com/cotes2020/jekyll-theme-chirpy/issues/new?labels=enhancement&template=feature_request.md) issue to discuss whether your idea fits the project.
|
||||
To ensure that the blog design is not confused, this project does not accept suggestions for design changes, such as color scheme, fonts, typography, etc. If your request is about an enhancement, it is recommended to first submit a [_Feature Request_](https://github.com/cotes2020/jekyll-theme-chirpy/issues/new?labels=enhancement&template=feature_request.md) issue to discuss whether your idea fits the project.
|
||||
|
||||
## Basic Process
|
||||
|
||||
Generally, contribute to the project by:
|
||||
|
||||
1. Fork this project on GitHub and clone it locally.
|
||||
2. Create a new branch from `master` and give it a descriptive name (e.g., `my-new-feature`, `fix-a-bug`).
|
||||
3. After completing the development, commit and push to remote.
|
||||
4. Submit a new pull request.
|
||||
2. Create a new branch from the default branch and give it a descriptive name (format: `feature/<add-new-feat>` / `fix/<fix-a-bug>`).
|
||||
3. After completing the development, submit a new _Pull Request_. Note that the commit message must follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), otherwise it will fail the PR check.
|
||||
|
||||
## Modifying JavaScript
|
||||
|
||||
If your contribution involves JavaScript modification, please read the following sections.
|
||||
|
||||
### Inline Scripts
|
||||
|
||||
If you need to add comments to the inline JavaScript (the code between the HTML tags `<script>` and `</script>`), please use `/* */` instead of two slashes `//`. Because the HTML will be compressed by [jekyll-compress-html](https://github.com/penibelst/jekyll-compress-html) during deployment, but it cannot handle the `//` properly, which will disrupt the structure of the compressed HTML.
|
||||
|
||||
### External Scripts
|
||||
|
||||
If you need to add/change/delete the JavaScript in the directory `_javascript/`, setting up [`Node.js`](https://nodejs.org/) and [`npx`](https://www.npmjs.com/package/npx) is a requirement. And then install the development dependencies:
|
||||
|
||||
```console
|
||||
$ npm i
|
||||
```
|
||||
|
||||
During JavaScript development, real-time debugging can be performed through the following commands:
|
||||
|
||||
Firstly, start a Jekyll server:
|
||||
|
||||
```console
|
||||
$ bash tools/run.sh
|
||||
```
|
||||
|
||||
And then open a new terminal tab and run:
|
||||
|
||||
```console
|
||||
# Type 'Ctrl + C' to stop
|
||||
$ npx gulp dev
|
||||
```
|
||||
|
||||
After debugging, run the command `npx gulp` (without any argument) will automatically output the compressed files to the directory `assets/js/dist/`.
|
||||
|
||||
## Verify the commit messages
|
||||
|
||||
If you want to make sure your commits pass the CI check, you can refer to the following steps.
|
||||
|
||||
Install `commitlint` & `husky`:
|
||||
|
||||
```console
|
||||
$ npm i -g @commitlint/{cli,config-conventional} husky
|
||||
```
|
||||
|
||||
And then enable `husky`:
|
||||
|
||||
```console
|
||||
$ husky install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
:tada: Your volunteering will make the open source world more beautiful, thanks again! :tada:
|
||||
:tada: Your volunteering will make the open-source world more beautiful, thanks again! :tada:
|
||||
|
||||
5
.github/FUNDING.yml
vendored
5
.github/FUNDING.yml
vendored
@@ -1,3 +1,2 @@
|
||||
custom:
|
||||
- https://www.buymeacoffee.com/coteschung
|
||||
- https://cotes.gitee.io/alipay-wechat-donation
|
||||
ko_fi: coteschung
|
||||
custom: https://sponsor.cotes.page
|
||||
|
||||
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
31
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -6,12 +6,15 @@ about: Create a report to help us improve
|
||||
<!-- NOTE: Please maintain all sections, otherwise the issue will be automatically closed :) -->
|
||||
|
||||
## Checklist
|
||||
<!-- Please complete the following list of tasks, and then check it by change the "[ ]" to "[x]" -->
|
||||
- [ ] I have read the [tutorials](https://chirpy.cotes.info/categories/tutorial/) and know the correct effect of the functional design.
|
||||
- [ ] There are no similar reports on existing issues (including closed ones).
|
||||
- [ ] I found the bug on the latest code of `master` branch.
|
||||
|
||||
<!-- Please complete the following list of tasks, and then check it by changing the "[ ]" to "[x]" -->
|
||||
|
||||
- [ ] I have read the [tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design.
|
||||
- [ ] There are no similar reports on [existing issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue) (including closed ones).
|
||||
- [ ] I found the bug on the latest code of the `master` branch.
|
||||
|
||||
## Describe the bug
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
### To Reproduce
|
||||
@@ -25,25 +28,32 @@ Steps to reproduce the behavior:
|
||||
-->
|
||||
|
||||
### Expected behavior
|
||||
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
### Screenshots
|
||||
|
||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||
|
||||
### Software
|
||||
<!-- Please complete the following information -->
|
||||
- Ruby version: <!-- by running: `ruby -v` -->
|
||||
- Gem version: <!-- by running: `gem -v`-->
|
||||
- Bundler version: <!-- by running: `bundle -v`-->
|
||||
- Jekyll version: <!-- by running: `bundle list | grep " jekyll "` -->
|
||||
### Environment
|
||||
|
||||
| Command | Version |
|
||||
|-----------------------------------|---------|
|
||||
| `ruby -v` | |
|
||||
| `gem -v` | |
|
||||
| `bundle -v` | |
|
||||
| `bundle exec jekyll -v` | |
|
||||
| `bundle info jekyll-theme-chirpy` | |
|
||||
|
||||
### Desktop
|
||||
|
||||
<!-- If necessary, uncomment and fill in the following list:
|
||||
- OS: [e.g. macOS 10.15.6]
|
||||
- Browser: [e.g. Chrome 85.0.4183.83 (64-bit)]
|
||||
-->
|
||||
|
||||
### Smartphone
|
||||
|
||||
<!-- If necessary, uncomment and fill in the following list:
|
||||
- Device: [e.g. iPhone 6]
|
||||
- OS: [e.g. iOS 13.6.1]
|
||||
@@ -51,4 +61,5 @@ Steps to reproduce the behavior:
|
||||
-->
|
||||
|
||||
### Additional context
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
||||
|
||||
9
.github/ISSUE_TEMPLATE/feature_request.md
vendored
9
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -7,24 +7,29 @@ labels: enhancement
|
||||
<!-- NOTE: Please maintain all sections, otherwise the issue will be automatically closed :) -->
|
||||
|
||||
## Checklist
|
||||
<!-- Please complete the following list of tasks, and then check it by change the "[ ]" to "[x]" -->
|
||||
|
||||
<!-- Please complete the following list of tasks, and then check it by changing the "[ ]" to "[x]" -->
|
||||
- [ ] I have read the [contributing guidelines](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/CONTRIBUTING.md).
|
||||
- [ ] There are no similar request on existing issues (including closed ones).
|
||||
- [ ] There is no similar request on [existing issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue) (including closed ones).
|
||||
- [ ] I have read the [project progress](https://github.com/cotes2020/jekyll-theme-chirpy/projects) and know the current progress of the project.
|
||||
- [ ] I was in the `master` branch of the latest code.
|
||||
|
||||
|
||||
## Is your feature request related to a problem? Please describe
|
||||
|
||||
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
|
||||
|
||||
|
||||
## Describe the solution you'd like
|
||||
|
||||
<!-- A clear and concise description of what you want to happen. -->
|
||||
|
||||
|
||||
## Describe alternatives you've considered
|
||||
|
||||
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
||||
|
||||
|
||||
## Additional context
|
||||
|
||||
<!-- Add any other context or screenshots about the feature request here. -->
|
||||
|
||||
13
.github/ISSUE_TEMPLATE/question.md
vendored
13
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask what ever you want
|
||||
about: Ask whatever you want
|
||||
labels: question
|
||||
---
|
||||
|
||||
@@ -8,12 +8,13 @@ labels: question
|
||||
|
||||
## Checklist
|
||||
|
||||
<!-- Please complete the following list of tasks, and then check it by change the "[ ]" to "[x]" -->
|
||||
<!-- Please complete the following list of tasks, and then check it by changing the "[ ]" to "[x]" -->
|
||||
|
||||
- [ ] I have read the [tutorials](https://chirpy.cotes.info/categories/tutorial/) and know the correct effect of the functional design.
|
||||
- [ ] There are no similar question on existing issues (including closed ones).
|
||||
- [ ] I searched the Internet for related problems, but still couldn't solve it.
|
||||
- [ ] My question is based on the latest code of `master` branch.
|
||||
- [ ] I have read the [newlest tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design.
|
||||
- [ ] There is no similar question on [existing issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue) (including closed ones).
|
||||
- [ ] I have tried to find the answer on [Jekyll Forum](https://talk.jekyllrb.com/) and [StackOverflow](https://stackoverflow.com/questions/tagged/jekyll).
|
||||
- [ ] My question is based on the latest code of the `master` branch.
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Please describe your question in detail. -->
|
||||
|
||||
24
.github/PULL_REQUEST_TEMPLATE.md
vendored
24
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,14 +1,14 @@
|
||||
## Description
|
||||
|
||||
<!--
|
||||
<!--
|
||||
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
|
||||
-->
|
||||
|
||||
e.g. Fixes #(issue)
|
||||
-->
|
||||
|
||||
## Type of change
|
||||
|
||||
<!--
|
||||
<!--
|
||||
Please select the desired item checkbox and change it to "[x]", then delete options that are not relevant.
|
||||
-->
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
@@ -18,27 +18,25 @@ Please select the desired item checkbox and change it to "[x]", then delete opti
|
||||
|
||||
## How has this been tested
|
||||
|
||||
<!--
|
||||
<!--
|
||||
Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration
|
||||
-->
|
||||
|
||||
- [ ] I have run `bash ./tools/test.sh --build` (at the root of the project) locally and passed
|
||||
- [ ] I have run `bash ./tools/test.sh` (at the root of the project) locally and passed
|
||||
- [ ] I have tested this feature in the browser
|
||||
|
||||
### Test Configuration
|
||||
|
||||
- Browser type & version:
|
||||
- Operating system:
|
||||
- Bundler version:
|
||||
- Ruby version:
|
||||
- Jekyll version:
|
||||
- Ruby version: <!-- by running: `ruby -v` -->
|
||||
- Bundler version: <!-- by running: `bundle -v`-->
|
||||
- Jekyll version: <!-- by running: `bundle list | grep " jekyll "` -->
|
||||
|
||||
### Checklist
|
||||
|
||||
<!-- Select checkboxes by change the "[ ]" to "[x]" -->
|
||||
- [ ] My code follows the [Google style guidelines](https://google.github.io/styleguide/)
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] I have performed a self-review of my code
|
||||
- [ ] I have commented on my code, particularly in hard-to-understand areas
|
||||
- [ ] I have made corresponding changes to the documentation
|
||||
- [ ] My changes generate no new warnings
|
||||
- [ ] I have added tests that prove my fix is effective or that my feature works
|
||||
- [ ] Any dependent changes have been merged and published in downstream modules
|
||||
|
||||
28
.github/workflows/ci.yml
vendored
28
.github/workflows/ci.yml
vendored
@@ -1,16 +1,16 @@
|
||||
name: 'Continuous Integration'
|
||||
name: 'CI'
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'production'
|
||||
- 'release/**'
|
||||
- 'docs'
|
||||
tags-ignore:
|
||||
- '*'
|
||||
- '**'
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
- '!.github/workflows/ci.yml'
|
||||
- '.travis.yml'
|
||||
- '.gitignore'
|
||||
- 'docs/**'
|
||||
- 'README.md'
|
||||
- 'LICENSE'
|
||||
pull_request:
|
||||
@@ -18,30 +18,24 @@ on:
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ${{ matrix.os }}
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
ruby: [2.5, 2.6, 2.7, 3]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # for posts's lastmod
|
||||
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.7
|
||||
ruby-version: ${{ matrix.ruby }}
|
||||
bundler-cache: true
|
||||
|
||||
- name: Build Site
|
||||
env:
|
||||
JEKYLL_ENV: production
|
||||
run: |
|
||||
bundle exec jekyll b
|
||||
|
||||
- name: Test Site
|
||||
run: |
|
||||
bash tools/test.sh
|
||||
run: bash tools/test.sh
|
||||
|
||||
11
.github/workflows/commitlint.yml
vendored
Normal file
11
.github/workflows/commitlint.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
name: Lint Commit Messages
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
commitlint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: wagoid/commitlint-github-action@v4
|
||||
72
.github/workflows/pages-deploy.yml.hook
vendored
72
.github/workflows/pages-deploy.yml.hook
vendored
@@ -1,53 +1,71 @@
|
||||
name: 'Automatic build'
|
||||
name: "Build and Deploy"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
paths-ignore:
|
||||
- .gitignore
|
||||
- README.md
|
||||
- LICENSE
|
||||
|
||||
jobs:
|
||||
continuous-delivery:
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow one concurrent deployment
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # for posts's lastmod
|
||||
fetch-depth: 0
|
||||
# submodules: true
|
||||
# If using the 'assets' git submodule from Chirpy Starter, uncomment above
|
||||
# (See: https://github.com/cotes2020/chirpy-starter/tree/main/assets)
|
||||
|
||||
- name: Setup Pages
|
||||
id: pages
|
||||
uses: actions/configure-pages@v1
|
||||
|
||||
- name: Setup Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 2.7
|
||||
ruby-version: 3 # reads from a '.ruby-version' or '.tools-version' file if 'ruby-version' is omitted
|
||||
bundler-cache: true
|
||||
|
||||
- name: Check baseurl
|
||||
run: |
|
||||
baseurl="$(grep '^baseurl:' _config.yml | sed "s/.*: *//;s/['\"]//g;s/#.*//")"
|
||||
if [[ -n $baseurl ]]; then
|
||||
echo "BASE_URL=$baseurl" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Build Site
|
||||
- name: Build site
|
||||
run: bundle exec jekyll b -d "_site${{ steps.pages.outputs.base_path }}"
|
||||
env:
|
||||
JEKYLL_ENV: production
|
||||
run: |
|
||||
bundle exec jekyll b -d "_site$BASE_URL"
|
||||
JEKYLL_ENV: "production"
|
||||
|
||||
- name: Test Site
|
||||
- name: Test site
|
||||
run: |
|
||||
bash tools/test.sh
|
||||
bundle exec htmlproofer _site --disable-external --check-html --allow_hash_href
|
||||
|
||||
- name: Deploy
|
||||
run: |
|
||||
if [[ -n $BASE_URL ]]; then
|
||||
mv _site$BASE_URL _site-rename
|
||||
rm -rf _site
|
||||
mv _site-rename _site
|
||||
fi
|
||||
- name: Upload site artifact
|
||||
uses: actions/upload-pages-artifact@v1
|
||||
with:
|
||||
path: "_site${{ steps.pages.outputs.base_path }}"
|
||||
|
||||
bash tools/deploy.sh
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v1
|
||||
|
||||
22
.github/workflows/style-lint.yml
vendored
Normal file
22
.github/workflows/style-lint.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: 'Style Lint'
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '_sass/**.scss'
|
||||
pull_request:
|
||||
paths:
|
||||
- '_sass/**.scss'
|
||||
|
||||
jobs:
|
||||
stylelint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
- run: npm i
|
||||
- run: npm test
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -4,6 +4,10 @@
|
||||
!.editorconfig
|
||||
!.nojekyll
|
||||
!.travis.yml
|
||||
!.husky
|
||||
!.commitlintrc.json
|
||||
!.versionrc.json
|
||||
!.stylelintrc.json
|
||||
|
||||
# bundler cache
|
||||
_site
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "assets/lib"]
|
||||
path = assets/lib
|
||||
url = https://github.com/cotes2020/chirpy-static-assets.git
|
||||
4
.husky/commit-msg
Executable file
4
.husky/commit-msg
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no -- commitlint -x $(npm root -g)/@commitlint/config-conventional --edit
|
||||
22
.stylelintrc.json
Normal file
22
.stylelintrc.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": "stylelint-config-standard-scss",
|
||||
"rules": {
|
||||
"no-descending-specificity": null,
|
||||
"shorthand-property-no-redundant-values": null,
|
||||
"at-rule-no-vendor-prefix": null,
|
||||
"property-no-vendor-prefix": null,
|
||||
"selector-no-vendor-prefix": null,
|
||||
"value-no-vendor-prefix": null,
|
||||
"color-function-notation": "legacy",
|
||||
"alpha-value-notation": "number",
|
||||
"selector-not-notation": "simple",
|
||||
"color-hex-length": "long",
|
||||
"declaration-block-single-line-max-declarations": 3,
|
||||
"font-family-no-missing-generic-family-keyword": [
|
||||
true,
|
||||
{
|
||||
"ignoreFontFamilies": ["Font Awesome 5 Free"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
67
.travis.yml
67
.travis.yml
@@ -1,49 +1,44 @@
|
||||
os: linux
|
||||
dist: bionic
|
||||
language: ruby
|
||||
rvm: 2.7.0
|
||||
|
||||
language: minimal
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libcurl4-openssl-dev # to avoid SSL error (for htmlproofer)
|
||||
|
||||
# Overriding to drop the `--development` flag which requires the Gemfile.lock at build
|
||||
install: bundle install --jobs=3 --retry=3 --path=vendor/bundle
|
||||
|
||||
before_script: git -C "$HOME" clone "$BUILDER_REPO" --depth=1 -q
|
||||
|
||||
jobs:
|
||||
include:
|
||||
|
||||
- name: CD
|
||||
language: ruby
|
||||
rvm: 2.7.0
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
# required to avoid SSL error (for htmlproofer)
|
||||
- libcurl4-openssl-dev
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $TRAVIS_BUILD_DIR/vendor/bundle
|
||||
|
||||
before_install:
|
||||
# match the Gemfile.lock, travis' bundler is 2.1.2
|
||||
- gem install bundler:2.2.4
|
||||
- bundle config path 'vendor/bundle'
|
||||
|
||||
install:
|
||||
# overriding to drop the travis `--development` flag
|
||||
- bundle install --jobs=3 --retry=3
|
||||
|
||||
script:
|
||||
- eval "$BUILD_CMD"
|
||||
|
||||
- stage: Upgrade
|
||||
cache: bundler
|
||||
git:
|
||||
depth: false # for posts' lastmod
|
||||
depth: false # for posts' lastmod
|
||||
script: eval "$BUILD_CMD"
|
||||
|
||||
- name: Flush Starter
|
||||
script:
|
||||
- eval "$FLUSH_STARTER"
|
||||
- stage: Starter
|
||||
language: minimal
|
||||
install: true # skip install step
|
||||
script: eval "$FLUSH_STARTER"
|
||||
|
||||
before_script:
|
||||
- git -C "$HOME" clone "$BUILDER_REPO" --depth=1 -q
|
||||
- stage: Docs
|
||||
cache: bundler
|
||||
git:
|
||||
depth: false # for posts' lastmod
|
||||
script: eval "$DOCS_CMD"
|
||||
|
||||
branches:
|
||||
only: /.*-stable$/
|
||||
stages:
|
||||
- name: Upgrade
|
||||
if: branch = production
|
||||
- name: Starter
|
||||
if: branch = production
|
||||
- name: Docs
|
||||
if: branch = docs
|
||||
|
||||
notifications:
|
||||
email:
|
||||
|
||||
20
.versionrc.json
Normal file
20
.versionrc.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"skip": {
|
||||
"commit": true,
|
||||
"tag": true
|
||||
},
|
||||
"types": [
|
||||
{
|
||||
"type": "feat",
|
||||
"section": "Features"
|
||||
},
|
||||
{
|
||||
"type": "fix",
|
||||
"section": "Bug Fixes"
|
||||
},
|
||||
{
|
||||
"type": "perf",
|
||||
"section": "Improvements"
|
||||
}
|
||||
]
|
||||
}
|
||||
107
CHANGELOG.md
Normal file
107
CHANGELOG.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [5.3.2](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v5.3.1...v5.3.2) (2022-11-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `mermaid` occasionally fails to initialize ([#536](https://github.com/cotes2020/jekyll-theme-chirpy/issues/536)) ([48f14e3](https://github.com/cotes2020/jekyll-theme-chirpy/commit/48f14e39ac81bbfb3b9913ea3ee789d775b2d1ae))
|
||||
* **comment:** disqus doesn't follow theme mode switching ([b0d5956](https://github.com/cotes2020/jekyll-theme-chirpy/commit/b0d5956f5a0ed894984d6b1754efeba04d8bc966))
|
||||
* restore full-text search ([#741](https://github.com/cotes2020/jekyll-theme-chirpy/issues/741)) ([6774e0e](https://github.com/cotes2020/jekyll-theme-chirpy/commit/6774e0e1fb37cf467b14be481347412713763f05))
|
||||
* the image URL in the SEO-related tags is incomplete ([#754](https://github.com/cotes2020/jekyll-theme-chirpy/issues/754)) ([f6e9a3f](https://github.com/cotes2020/jekyll-theme-chirpy/commit/f6e9a3fccf7ab34db71f8aefaf86fdcc05861076))
|
||||
|
||||
## [5.3.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v5.3.0...v5.3.1) (2022-10-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* 404 page missing title in tablet/desktop view ([5511b28](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5511b2883fd5a395fddfb642588d00c122f18da7))
|
||||
* prompt content overflows horizontally ([#705](https://github.com/cotes2020/jekyll-theme-chirpy/issues/705)) ([fb13e32](https://github.com/cotes2020/jekyll-theme-chirpy/commit/fb13e3219b5eca0d2e4f86a1ecabfab75240369f))
|
||||
* **tools:** multiple configuration files will fail the test ([80cb0b3](https://github.com/cotes2020/jekyll-theme-chirpy/commit/80cb0b371754e96772a7907877a8ce196398ba3d))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* **layout:** improve the min-height of main content ([#674](https://github.com/cotes2020/jekyll-theme-chirpy/issues/674)) ([49bb93c](https://github.com/cotes2020/jekyll-theme-chirpy/commit/49bb93cc0c89ad9cfaad5edcf9cb28c3d5134575))
|
||||
* modify checkbox icon with `Liquid` ([1fd665b](https://github.com/cotes2020/jekyll-theme-chirpy/commit/1fd665bf4990c26ae23635c511c5abc9640184d1))
|
||||
* optimize the extra padding in lists ([#703](https://github.com/cotes2020/jekyll-theme-chirpy/issues/703)) ([39da11e](https://github.com/cotes2020/jekyll-theme-chirpy/commit/39da11e3f3685f49321757576d2b87a48bf25db5)), closes [#702](https://github.com/cotes2020/jekyll-theme-chirpy/issues/702)
|
||||
* **posts:** improve core block bottom padding ([d2fb98b](https://github.com/cotes2020/jekyll-theme-chirpy/commit/d2fb98b3e57f2f6c3fc3816551cd0721731adf40))
|
||||
* truncate post content for search results ([647eea8](https://github.com/cotes2020/jekyll-theme-chirpy/commit/647eea8dbd716f9d3cb8330c3139fa753903f51d))
|
||||
* **typography:** optimize the line height of post content ([eac3f9b](https://github.com/cotes2020/jekyll-theme-chirpy/commit/eac3f9b434ca77e3dc64eea9cedea7b93e7b306b))
|
||||
|
||||
### Others
|
||||
|
||||
* **giscus:** add `reactions-enabled` option ([#712](https://github.com/cotes2020/jekyll-theme-chirpy/issues/712)) ([70662a0](https://github.com/cotes2020/jekyll-theme-chirpy/commit/70662a0365e6b9378602dc0a57462ddad5aebcf5))
|
||||
* **locale:** restore options for changing date format ([#716](https://github.com/cotes2020/jekyll-theme-chirpy/issues/716)) ([f904e8c](https://github.com/cotes2020/jekyll-theme-chirpy/commit/f904e8cd48c343cc31e25859d9d50bfe2c056f41))
|
||||
* remove site config option `prefer_datetime_locale` ([6852ceb](https://github.com/cotes2020/jekyll-theme-chirpy/commit/6852ceb280927ff4e753a3e1131f2b396d9807d0))
|
||||
|
||||
## [5.3.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v5.2.1...v5.3.0) (2022-09-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add multiple authors to a post ([#677](https://github.com/cotes2020/jekyll-theme-chirpy/issues/677)) ([f1d9e99](https://github.com/cotes2020/jekyll-theme-chirpy/commit/f1d9e99bc02d3cd0a6b0cd1beac545f0cc7a24f8)), closes [#675](https://github.com/cotes2020/jekyll-theme-chirpy/issues/675)
|
||||
* **i18n:** add Bulgarian support ([#612](https://github.com/cotes2020/jekyll-theme-chirpy/issues/612)) ([2fed338](https://github.com/cotes2020/jekyll-theme-chirpy/commit/2fed338ce6d078bf528c9717201fbc475f88cd22))
|
||||
* **i18n:** add German locale file ([#663](https://github.com/cotes2020/jekyll-theme-chirpy/issues/663)) ([940b281](https://github.com/cotes2020/jekyll-theme-chirpy/commit/940b2810e95065e30600ae8d5e4612e7183da60e))
|
||||
* **i18n:** add Hungarian locale file ([#597](https://github.com/cotes2020/jekyll-theme-chirpy/issues/597), [#598](https://github.com/cotes2020/jekyll-theme-chirpy/issues/598)) ([b032977](https://github.com/cotes2020/jekyll-theme-chirpy/commit/b0329775fc24d0323e5cc04cda46ece8b4531802))
|
||||
* **i18n:** add Turkish language ([#631](https://github.com/cotes2020/jekyll-theme-chirpy/issues/631)) ([ad137fa](https://github.com/cotes2020/jekyll-theme-chirpy/commit/ad137fa2945b1870b9c1dd5e9212a5f4af7c3580))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add missing color to linkedin icon for share list ([#683](https://github.com/cotes2020/jekyll-theme-chirpy/issues/683)) ([0dcd39d](https://github.com/cotes2020/jekyll-theme-chirpy/commit/0dcd39d491c9c49e4acf7f75f83fe6e1d1839e37))
|
||||
* code contains spaces in headings ([#644](https://github.com/cotes2020/jekyll-theme-chirpy/issues/644)) ([3fa1bf3](https://github.com/cotes2020/jekyll-theme-chirpy/commit/3fa1bf305451f645a7f3aa93863b076463c8f165))
|
||||
* correct spelling of `panel` ([#686](https://github.com/cotes2020/jekyll-theme-chirpy/issues/686)) ([b288587](https://github.com/cotes2020/jekyll-theme-chirpy/commit/b288587c1c3d113a1c52c2d25fb46cddda348961))
|
||||
* correct the i18n for tab titles ([0c5b697](https://github.com/cotes2020/jekyll-theme-chirpy/commit/0c5b697fd3b283b6a5c926742b61ed49d8688c18))
|
||||
* the `code` doesn't wrap inside the prompt ([#626](https://github.com/cotes2020/jekyll-theme-chirpy/issues/626)) ([378b65a](https://github.com/cotes2020/jekyll-theme-chirpy/commit/378b65a0617787813519dde74d6f741f255eff3d))
|
||||
|
||||
## [5.2.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v5.2.0...v5.2.1) (2022-06-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* exclude CHANGELOG from output ([971fe03](https://github.com/cotes2020/jekyll-theme-chirpy/commit/971fe03ec329ae49e7d60fe3af6101cfbd1acd6c))
|
||||
* **PWA:** sometimes update notification is not triggered ([96af729](https://github.com/cotes2020/jekyll-theme-chirpy/commit/96af7291ea5b2c5ed6372e7b6f7725e67c69f1ba))
|
||||
|
||||
## [5.2.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v5.1.0...v5.2.0) (2022-06-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add es-ES support to locales ([#533](https://github.com/cotes2020/jekyll-theme-chirpy/issues/533)) ([efe75ad](https://github.com/cotes2020/jekyll-theme-chirpy/commit/efe75adf2784956afb7a0b67f6634b146d9cb03b))
|
||||
* add fr-FR support to locales ([#582](https://github.com/cotes2020/jekyll-theme-chirpy/issues/582)) ([94e8144](https://github.com/cotes2020/jekyll-theme-chirpy/commit/94e81447afa457b1a6b7e8f487c47502803556d7))
|
||||
* add Vietnamese locale ([#517](https://github.com/cotes2020/jekyll-theme-chirpy/issues/517)) ([171463d](https://github.com/cotes2020/jekyll-theme-chirpy/commit/171463d76da9b7bc25dd327b8f0a868ea79e388b))
|
||||
* add pt-BR support to locales ([c2c503f](https://github.com/cotes2020/jekyll-theme-chirpy/commit/c2c503f63336884282b6bda4ec0703d6ae76771b))
|
||||
* add option to turn off PWA ([#527](https://github.com/cotes2020/jekyll-theme-chirpy/issues/527)) ([106c981](https://github.com/cotes2020/jekyll-theme-chirpy/commit/106c981bac71e7434204a77e1f0c9c61d6eb1509))
|
||||
* **PWA:** add Service Worker update notification ([d127183](https://github.com/cotes2020/jekyll-theme-chirpy/commit/d127183b9774f6321e409acdb66bf8a85d8814be))
|
||||
* support showing description of preview image ([2bd6efa](https://github.com/cotes2020/jekyll-theme-chirpy/commit/2bd6efa95a174ac44e30a3af1e57e6f40d6e0e3a))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* alt is not a valid attribute for 'a' tag ([58928db](https://github.com/cotes2020/jekyll-theme-chirpy/commit/58928dbc9068db4e4cda4371eeae1865920dce6a))
|
||||
* assets URL is missing `baseurl` in self-hosted mode ([#591](https://github.com/cotes2020/jekyll-theme-chirpy/issues/591)) ([54124d5](https://github.com/cotes2020/jekyll-theme-chirpy/commit/54124d5134995fce52e4c2fc0a5d4d1743d6264d))
|
||||
* correct the `twitter:creator` of Twitter summary card ([96a16c8](https://github.com/cotes2020/jekyll-theme-chirpy/commit/96a16c868ede51e7dfa412de63ffa1e5a49add7f))
|
||||
* correctly URL encode share links ([4c1c8d8](https://github.com/cotes2020/jekyll-theme-chirpy/commit/4c1c8d8b0eacecbbaa2d522bbdd6430f350ff760)), closes [#496](https://github.com/cotes2020/jekyll-theme-chirpy/issues/496)
|
||||
* follow paginate_path config for pagination ([6900d9f](https://github.com/cotes2020/jekyll-theme-chirpy/commit/6900d9f2bc9380cbda4babf611c6eeff345291af))
|
||||
* force checkout of `gh-pages` branch ([#544](https://github.com/cotes2020/jekyll-theme-chirpy/issues/544)) ([5402523](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5402523ae52a3740bcc15df0b226b2612644945d))
|
||||
* horizontal scroll for long equations ([#545](https://github.com/cotes2020/jekyll-theme-chirpy/issues/545)) ([30787fc](https://github.com/cotes2020/jekyll-theme-chirpy/commit/30787fc4cf151e955bb7afc26dfd859f1a06fce6))
|
||||
* p is not allowed in span ([4f590e2](https://github.com/cotes2020/jekyll-theme-chirpy/commit/4f590e2bba0639751771211bc0d357828ae70404))
|
||||
* remove whitespace from avatar URL ([#537](https://github.com/cotes2020/jekyll-theme-chirpy/issues/537)) ([0542b51](https://github.com/cotes2020/jekyll-theme-chirpy/commit/0542b5149c8287dca60e37f46ee36f31b43455e4))
|
||||
* resume the preview image SEO tag ([#529](https://github.com/cotes2020/jekyll-theme-chirpy/issues/529)) ([b8d1bcd](https://github.com/cotes2020/jekyll-theme-chirpy/commit/b8d1bcd3dea0abd1afef7ef154a4501fbb18938d))
|
||||
* script code should be in head or body, not in between ([2103191](https://github.com/cotes2020/jekyll-theme-chirpy/commit/2103191b2faf714a8e4418c7c347a1f942b51af8))
|
||||
* spurious header closing tags ([59e9557](https://github.com/cotes2020/jekyll-theme-chirpy/commit/59e955745f02f9b57c65af70b0979cd4a98bf53f))
|
||||
* table bypass refactoring when it contains IAL ([#519](https://github.com/cotes2020/jekyll-theme-chirpy/issues/519)) ([5d85ccb](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5d85ccb9943aac88dbbefebe1c2234cdcbae5c53))
|
||||
* **theme mode:** `SCSS` syntax error ([#588](https://github.com/cotes2020/jekyll-theme-chirpy/issues/588)) ([76a1b6a](https://github.com/cotes2020/jekyll-theme-chirpy/commit/76a1b6a068c369138422dcd18ba08ec8cc3749a6))
|
||||
* use `jsonify` to generate valid json ([#521](https://github.com/cotes2020/jekyll-theme-chirpy/issues/521)) ([dd9d5a7](https://github.com/cotes2020/jekyll-theme-chirpy/commit/dd9d5a7207b746342d07176d8969dc4f2c380bf2))
|
||||
* when the `site.img_cdn` is set to the local path, the preview-image path loses the `baseurl` ([9cefe58](https://github.com/cotes2020/jekyll-theme-chirpy/commit/9cefe58993d9ea3a3a28424e7ffd8e0911567c5c))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* avoid post pageviews from shifting while loading ([135a16f](https://github.com/cotes2020/jekyll-theme-chirpy/commit/135a16f13ee783d9308669ff9a824847a73c951c))
|
||||
* avoid the layout shift for post datetime ([6d35f5f](https://github.com/cotes2020/jekyll-theme-chirpy/commit/6d35f5f8da044cfad071628bb53776de03efaae4))
|
||||
* **categories:** support singular and plural forms of locale ([#595](https://github.com/cotes2020/jekyll-theme-chirpy/issues/595)) ([35cadf9](https://github.com/cotes2020/jekyll-theme-chirpy/commit/35cadf969dd0161ee62503e242c545f006f7072b))
|
||||
* improve the responsive design for ultrawide screens ([#540](https://github.com/cotes2020/jekyll-theme-chirpy/issues/540)) ([5d6e8c5](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5d6e8c5ef6aa71b4d2600c5305f6e8ba540557f7))
|
||||
3
Gemfile
3
Gemfile
@@ -17,3 +17,6 @@ end
|
||||
|
||||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.1", :install_if => Gem.win_platform?
|
||||
|
||||
# Jekyll <= 4.2.0 compatibility with Ruby 3.0
|
||||
gem "webrick", "~> 1.7"
|
||||
|
||||
217
README.md
217
README.md
@@ -1,238 +1,97 @@
|
||||
<div align="right">
|
||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy#readme">EN</a> |
|
||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/README.zh-CN.md">中文 (简体)</a>
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<h1>Chirpy Jekyll Theme</h1>
|
||||
<p>
|
||||
<a href="https://rubygems.org/gems/jekyll-theme-chirpy">
|
||||
<img alt="Gem Version" src="https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen"></img>
|
||||
</a>
|
||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush">
|
||||
<img alt="Build Status" src="https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?branch=master&event=push"></img>
|
||||
</a>
|
||||
<a href="https://app.codacy.com/manual/cotes2020/jekyll-theme-chirpy?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade_Dashboard">
|
||||
<img alt="Codacy Badge" src="https://api.codacy.com/project/badge/Grade/8220b926db514f13afc3f02b7f884f4b"></img>
|
||||
</a>
|
||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE">
|
||||
<img alt="GitHub license" src="https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg"></img>
|
||||
</a>
|
||||
<a href="https://996.icu">
|
||||
<img alt="996.icu" src="https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg"></img>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
# Chirpy Jekyll Theme
|
||||
|
||||
A minimal, responsive, and powerful Jekyll theme for presenting professional writing.
|
||||
|
||||
[](https://rubygems.org/gems/jekyll-theme-chirpy)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml)
|
||||
[](https://www.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=github.com&utm_medium=referral&utm_content=cotes2020/jekyll-theme-chirpy&utm_campaign=Badge_Grade)
|
||||
[](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
|
||||
[](https://996.icu)
|
||||
|
||||
[**Live Demo →**](https://cotes2020.github.io/chirpy-demo)
|
||||
|
||||
[](https://cotes2020.github.io/chirpy-demo)
|
||||
|
||||
</div>
|
||||
|
||||
A minimal, sidebar, responsive web design Jekyll theme that focuses on text presentation. Designed to help you easily record and share your knowledge.
|
||||
|
||||
[Live Demo »](https://chirpy.cotes.info)
|
||||
|
||||
<p align="center">
|
||||
<a href="https://chirpy.cotes.info">
|
||||
<img alt="Devices Mockup" src="https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png"></img>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Features
|
||||
|
||||
- Localized Layout
|
||||
- Configurable Theme Mode
|
||||
- Dark/Light Theme Mode
|
||||
- Pinned Posts
|
||||
- Hierarchical Categories
|
||||
- Last Modified Date for Posts
|
||||
- Table of Contents
|
||||
- Automatically Recommend Related Posts
|
||||
- Auto-generated Related Posts
|
||||
- Syntax Highlighting
|
||||
- Mathematical Expressions
|
||||
- Mermaid Diagram & Flowchart
|
||||
- Disqus/Utterances/Giscus Comments
|
||||
- Search
|
||||
- Atom Feeds
|
||||
- Disqus Comments
|
||||
- Google Analytics
|
||||
- GA Pageviews Reporting (Advanced)
|
||||
- GA Pageviews Reporting
|
||||
- SEO & Performance Optimization
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`. Please note that the version of `Ruby` must meet the requirements of the theme on [RubyGems.org](https://rubygems.org/gems/jekyll-theme-chirpy).
|
||||
## Quick Start
|
||||
|
||||
## Installation
|
||||
Before starting, please follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll`, and `Bundler`. In addition, [Git](https://git-scm.com/) is also required to be installed.
|
||||
|
||||
There are two ways to get the theme:
|
||||
### Step 1. Creating a New Site
|
||||
|
||||
- **[Install from RubyGems](#install-from-rubygems)** - Easy to update, isolate irrelevant project files so you can focus on writing.
|
||||
- **[Fork on GitHub](#fork-on-github)** - Convenient for custom development, but difficult to update, only suitable for web developers.
|
||||
Create a new repository from the [**Chirpy Starter**](https://github.com/cotes2020/chirpy-starter/generate) and name it `<GH_USERNAME>.github.io`, where `GH_USERNAME` represents your GitHub username.
|
||||
|
||||
### Install from RubyGems
|
||||
### Step 2. Installing Dependencies
|
||||
|
||||
Add this line to your Jekyll site's `Gemfile`:
|
||||
|
||||
```ruby
|
||||
gem "jekyll-theme-chirpy"
|
||||
```
|
||||
|
||||
And add this line to your Jekyll site's `_config.yml`:
|
||||
|
||||
```yaml
|
||||
theme: jekyll-theme-chirpy
|
||||
```
|
||||
|
||||
And then execute:
|
||||
Before running for the first time, go to the root directory of your site, and install dependencies as follows:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
|
||||
Next, go to the installed local theme path:
|
||||
### Step 3. Running Local Server
|
||||
|
||||
```console
|
||||
$ cd "$(bundle info --path jekyll-theme-chirpy)"
|
||||
```
|
||||
|
||||
And then copy the critical files (for details, see [starter project][starter]) from the theme's gem to your Jekyll site.
|
||||
|
||||
> ⚠️ **Watch out for duplicate files!**
|
||||
>
|
||||
If your Jekyll site is created by the `jekyll new` command, there will be `index.markdown` and `about.markdown` in the root directory of your site. Please be sure to remove them, otherwise they will overwrite the `index.html` and `_tabs/about.html` from this project, resulting in blank or messy pages.
|
||||
|
||||
As an alternative, which we recommend, you can create a Jekyll site [**using the starter template**][use-starter] to save time copying files from the theme's gem. We've prepared everything you need there!
|
||||
|
||||
### Fork on GitHub
|
||||
|
||||
[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) on GitHub and then clone your fork to local. (Please note that the default branch code is in development. If you want the blog to be stable, please switch to the [latest tag](https://github.com/cotes2020/jekyll-theme-chirpy/tags) and start writing.)
|
||||
|
||||
Install gem dependencies by:
|
||||
|
||||
```console
|
||||
$ bundle
|
||||
```
|
||||
|
||||
And then execute:
|
||||
|
||||
```console
|
||||
$ bash tools/init.sh
|
||||
```
|
||||
|
||||
> **Note**: If you don't plan to deploy your site on GitHub Pages, append parameter option `--no-gh` at the end of the above command.
|
||||
|
||||
What it does is:
|
||||
|
||||
1. Remove some files or directories from your repository:
|
||||
- `.travis.yml`
|
||||
- files under `_posts`
|
||||
- folder `docs`
|
||||
|
||||
2. If you use the `--no-gh` option, the directory `.github` will be deleted. Otherwise, setup the GitHub Action workflow by removing the extension `.hook` of `.github/workflows/pages-deploy.yml.hook`, and then remove the other files and directories in the folder `.github`.
|
||||
|
||||
3. Automatically create a commit to save the changes.
|
||||
|
||||
## Usage
|
||||
|
||||
### Configuration
|
||||
|
||||
Update the variables of `_config.yml` as needed. Some of them are typical options:
|
||||
|
||||
- `url`
|
||||
- `avatar`
|
||||
- `timezone`
|
||||
- `lang`
|
||||
|
||||
### Customing Stylesheet
|
||||
|
||||
If you need to customize stylesheet, copy the theme's `assets/css/style.scss` to the same path on your Jekyll site, and then add the custom style at the end of the style file.
|
||||
|
||||
Starting from `v4.1.0`, if you want to overwrite the SASS variables defined in `_sass/addon/variables.scss`, create a new file `_sass/variables-hook.scss` and assign new values to the target variable in it.
|
||||
|
||||
### Running Local Server
|
||||
|
||||
You may want to preview the site contents before publishing, so just run it by:
|
||||
Run the following command in the root directory of the site:
|
||||
|
||||
```console
|
||||
$ bundle exec jekyll s
|
||||
```
|
||||
|
||||
Or run the site on Docker with the following command:
|
||||
Or run with Docker:
|
||||
|
||||
```terminal
|
||||
```console
|
||||
$ docker run -it --rm \
|
||||
--volume="$PWD:/srv/jekyll" \
|
||||
-p 4000:4000 jekyll/jekyll \
|
||||
jekyll serve
|
||||
```
|
||||
|
||||
Open a browser and visit to _<http://localhost:4000>_.
|
||||
|
||||
### Deployment
|
||||
|
||||
Before the deployment begins, checkout the file `_config.yml` and make sure the `url` is configured correctly. Furthermore, if you prefer the [**project site**](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites) and don't use a custom domain, or you want to visit your website with a base URL on a web server other than **GitHub Pages**, remember to change the `baseurl` to your project name that starting with a slash, e.g, `/project-name`.
|
||||
|
||||
Now you can choose ONE of the following methods to deploy your Jekyll site.
|
||||
|
||||
#### Deploy on GitHub Pages
|
||||
|
||||
For security reasons, GitHub Pages build runs on `safe` mode, which restricts us from using plugins to generate additional page files. Therefore, we can use **GitHub Actions** to build the site, store the built site files on a new branch, and use that branch as the source of the GH Pages service.
|
||||
|
||||
Quickly check the files needed for GitHub Actions build:
|
||||
|
||||
- Ensure your Jekyll site has the file `.github/workflows/pages-deploy.yml`. Otherwise, create a new one and fill in the contents of the [workflow file][workflow], and the value of the `on.push.branches` should be the same as your repo's default branch name.
|
||||
- Ensure your Jekyll site has file `tools/test.sh` and `tools/deploy.sh`. Otherwise, copy them from this repo to your Jekyll site.
|
||||
|
||||
And then rename your repository to `<GH-USERNAME>.github.io` on GitHub.
|
||||
|
||||
Now publish your Jekyll site by:
|
||||
|
||||
1. Push any commit to remote to trigger the GitHub Actions workflow. Once the build is complete and successful, a new remote branch named `gh-pages` will appear to store the built site files.
|
||||
|
||||
2. Browse to your repo's landing page on GitHub and select the branch `gh-pages` as the [publishing source](https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site) through _Settings_ → _Options_ → _GitHub Pages_:
|
||||
|
||||

|
||||
|
||||
3. Visit your website at the address indicated by GitHub.
|
||||
|
||||
#### Deploy on Other Platforms
|
||||
|
||||
On platforms other than GitHub, we cannot enjoy the convenience of **GitHub Actions**. Therefore, we should build the site locally (or on some other 3rd-party CI platform) and then put the site files on the server.
|
||||
|
||||
Go to the root of the source project, build your site by:
|
||||
|
||||
```console
|
||||
$ JEKYLL_ENV=production bundle exec jekyll b
|
||||
```
|
||||
|
||||
Or build the site with Docker by:
|
||||
|
||||
```terminal
|
||||
$ docker run -it --rm \
|
||||
--env JEKYLL_ENV=production \
|
||||
--volume="$PWD:/srv/jekyll" \
|
||||
jekyll/jekyll \
|
||||
jekyll build
|
||||
```
|
||||
|
||||
Unless you specified the output path, the generated site files will be placed in folder `_site` of the project's root directory. Now you should upload those files to your web server.
|
||||
After a while, navigate to the site at <http://localhost:4000>.
|
||||
|
||||
## Documentation
|
||||
|
||||
For more details and a better reading experience, please check out the [tutorials on the demo site](https://chirpy.cotes.info/categories/tutorial/). In the meanwhile, a copy of the tutorial is also available on the [Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki). Please note that the tutorials on the demo website or Wiki are based on the latest release, and the features of `master` branch usually ahead of the documentation.
|
||||
For more details on usage, please refer to the tutorial on the [demo website](https://cotes2020.github.io/chirpy-demo/) / [wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki). Note that the tutorial is based on the [latest release](https://github.com/cotes2020/jekyll-theme-chirpy/releases/latest), and the features of the default branch are usually ahead of the documentation.
|
||||
|
||||
## Contributing
|
||||
|
||||
The old saying, "Two heads are better than one." Consequently, welcome to report bugs, improve code quality or submit a new feature. For more information, see [contributing guidelines](.github/CONTRIBUTING.md).
|
||||
Welcome to report bugs, improve code quality or submit a new feature. For more information, see [contributing guidelines](.github/CONTRIBUTING.md).
|
||||
|
||||
## Credits
|
||||
|
||||
This theme is mainly built with [Jekyll](https://jekyllrb.com/) ecosystem, [Bootstrap](https://getbootstrap.com/), [Font Awesome](https://fontawesome.com/) and some other wonderful tools (their copyright information can be found in the relevant files). The avatar and favicon design comes from [Clipart Max](https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/).
|
||||
This theme is mainly built with [Jekyll](https://jekyllrb.com/) ecosystem, [Bootstrap](https://getbootstrap.com/), [Font Awesome](https://fontawesome.com/) and some other wonderful tools (their copyright information can be found in the relevant files). The avatar and favicon design come from [Clipart Max](https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/).
|
||||
|
||||
:tada: Thanks to all the volunteers who contributed to this project, their GitHub IDs are on [this list](https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors). Also, I won't forget those guys who submitted the issues or unmerged PR because they reported bugs, shared ideas, or inspired me to write more readable documentation.
|
||||
|
||||
Last but not least, thank [JetBrains][jb] for providing the open source license.
|
||||
Last but not least, thank [JetBrains][jb] for providing the OSS development license.
|
||||
|
||||
## Sponsoring
|
||||
|
||||
If you like this theme or find it helpful, please consider sponsoring me, because it will encourage and help me better maintain the project, I will be very grateful!
|
||||
|
||||
[](https://www.buymeacoffee.com/coteschung)
|
||||
[](https://ko-fi.com/coteschung)
|
||||
[][cn-donation]
|
||||
[][cn-donation]
|
||||
|
||||
@@ -240,11 +99,7 @@ If you like this theme or find it helpful, please consider sponsoring me, becaus
|
||||
|
||||
This work is published under [MIT](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE) License.
|
||||
|
||||
[starter]: https://github.com/cotes2020/chirpy-starter
|
||||
[use-starter]: https://github.com/cotes2020/chirpy-starter/generate
|
||||
[workflow]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/workflows/pages-deploy.yml.hook
|
||||
|
||||
<!-- ReadMe links -->
|
||||
|
||||
[jb]: https://www.jetbrains.com/?from=jekyll-theme-chirpy
|
||||
[cn-donation]: https://cotes.gitee.io/alipay-wechat-donation/
|
||||
[cn-donation]: https://sponsor.cotes.page/
|
||||
|
||||
88
_config.yml
88
_config.yml
@@ -3,18 +3,15 @@
|
||||
# Import the theme
|
||||
theme: jekyll-theme-chirpy
|
||||
|
||||
# Only if your site type is GitHub Project sites and doesn't have a custom domain,
|
||||
# change below value to '/projectname'.
|
||||
# Change the following value to '/PROJECT_NAME' ONLY IF your site type is GitHub Pages Project sites
|
||||
# and doesn't have a custom domain.
|
||||
baseurl: ''
|
||||
|
||||
# The language of the site layout › http://www.lingoes.net/en/translator/langcode.htm
|
||||
# Go to folder '_data/locales' to check the available language options
|
||||
# The language of the webpage › http://www.lingoes.net/en/translator/langcode.htm
|
||||
# If it has the same name as one of the files in folder `_data/locales`, the layout language will also be changed,
|
||||
# otherwise, the layout language will use the default value of 'en'.
|
||||
lang: en
|
||||
|
||||
# The lang attribute of HTML › http://www.lingoes.net/en/translator/langcode.htm
|
||||
# We can specify a language different from the layout of the content.
|
||||
# If it is not assigned, the site will use the value of 'lang' instead.
|
||||
content_lang: ''
|
||||
|
||||
# Change to your timezone › http://www.timezoneconverter.com/cgi-bin/findzone/findzone
|
||||
timezone: Asia/Shanghai
|
||||
@@ -27,9 +24,7 @@ title: Chirpy # the main title
|
||||
tagline: A text-focused Jekyll theme # it will display as the sub-title
|
||||
|
||||
description: >- # used by seo meta and the atom feed
|
||||
A minimal, portfolio, sidebar,
|
||||
bootstrap Jekyll theme with responsive web design
|
||||
and focuses on text presentation.
|
||||
A minimal, responsive, and powerful Jekyll theme for presenting professional writing.
|
||||
|
||||
# fill in the protocol & hostname for your site, e.g., 'https://username.github.io'
|
||||
url: ''
|
||||
@@ -44,7 +39,7 @@ social:
|
||||
# Change to your full name.
|
||||
# It will be displayed as the default author of the posts and the copyright owner in the Footer
|
||||
name: your_full_name
|
||||
email: example@doamin.com # change to your email address
|
||||
email: example@domain.com # change to your email address
|
||||
links:
|
||||
# The first element serves as the copyright owner's link
|
||||
- https://twitter.com/username # change to your twitter homepage
|
||||
@@ -53,13 +48,13 @@ social:
|
||||
# - https://www.facebook.com/username
|
||||
# - https://www.linkedin.com/in/username
|
||||
|
||||
google_site_verification: google_meta_tag_verification # change to your verification string
|
||||
google_site_verification: # fill in to your verification string
|
||||
|
||||
# ↑ --------------------------
|
||||
|
||||
# The end of `jekyll-seo-tag` settings
|
||||
|
||||
google_analytics:
|
||||
id: '' # fill in your Google Analytics ID
|
||||
id: # fill in your Google Analytics ID
|
||||
# Google Analytics pageviews report settings
|
||||
pv:
|
||||
proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine
|
||||
@@ -83,17 +78,44 @@ theme_mode: # [light|dark]
|
||||
# will be added to all image (site avatar & posts' images) paths starting with '/'
|
||||
#
|
||||
# e.g. 'https://cdn.com'
|
||||
img_cdn: ''
|
||||
img_cdn: 'https://demo-img.cotes.page'
|
||||
|
||||
# the avatar on sidebar, support local or CORS resources
|
||||
avatar: https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/avatar.jpg
|
||||
avatar: '/commons/avatar.jpg'
|
||||
|
||||
# boolean type, the global switch for ToC in posts.
|
||||
toc: true
|
||||
|
||||
disqus:
|
||||
comments: false # boolean type, the global switch for posts comments.
|
||||
shortname: '' # Fill with your Disqus shortname. › https://help.disqus.com/en/articles/1717111-what-s-a-shortname
|
||||
comments:
|
||||
active: # The global switch for posts comments, e.g., 'disqus'. Keep it empty means disable
|
||||
# The active options are as follows:
|
||||
disqus:
|
||||
shortname: # fill with the Disqus shortname. › https://help.disqus.com/en/articles/1717111-what-s-a-shortname
|
||||
# utterances settings › https://utteranc.es/
|
||||
utterances:
|
||||
repo: # <gh-username>/<repo>
|
||||
issue_term: # < url | pathname | title | ...>
|
||||
# Giscus options › https://giscus.app
|
||||
giscus:
|
||||
repo: # <gh-username>/<repo>
|
||||
repo_id:
|
||||
category:
|
||||
category_id:
|
||||
mapping: # optional, default to 'pathname'
|
||||
input_position: # optional, default to 'bottom'
|
||||
lang: # optional, default to the value of `site.lang`
|
||||
reactions_enabled: # optional, default to the value of `1`
|
||||
|
||||
# Self-hosted static assets, optional › https://github.com/cotes2020/chirpy-static-assets
|
||||
assets:
|
||||
self_host:
|
||||
enabled: # boolean, keep empty means false
|
||||
# specify the Jekyll environment, empty means both
|
||||
# only works if `assets.self_host.enabled` is 'true'
|
||||
env: # [development|production]
|
||||
|
||||
pwa:
|
||||
enabled: true # the option for PWA feature
|
||||
|
||||
paginate: 10
|
||||
|
||||
@@ -115,10 +137,8 @@ collections:
|
||||
output: true
|
||||
sort_by: order
|
||||
|
||||
|
||||
defaults:
|
||||
-
|
||||
scope:
|
||||
- scope:
|
||||
path: '' # An empty string here means all files in the project
|
||||
type: posts
|
||||
values:
|
||||
@@ -128,19 +148,24 @@ defaults:
|
||||
# DO NOT modify the following parameter unless you are confident enough
|
||||
# to update the code of all other post links in this project.
|
||||
permalink: /posts/:title/
|
||||
-
|
||||
scope:
|
||||
- scope:
|
||||
path: _drafts
|
||||
values:
|
||||
comments: false
|
||||
-
|
||||
scope:
|
||||
- scope:
|
||||
path: ''
|
||||
type: tabs # see `site.collections`
|
||||
values:
|
||||
layout: page
|
||||
permalink: /:title/
|
||||
dynamic_title: true # Hide title in mobile screens.
|
||||
- scope:
|
||||
path: assets/img/favicons
|
||||
values:
|
||||
swcache: true
|
||||
- scope:
|
||||
path: assets/js/dist
|
||||
values:
|
||||
swcache: true
|
||||
|
||||
sass:
|
||||
style: compressed
|
||||
@@ -158,12 +183,12 @@ exclude:
|
||||
- '*.gem'
|
||||
- '*.gemspec'
|
||||
- tools
|
||||
- docs
|
||||
- README.md
|
||||
- CHANGELOG.md
|
||||
- LICENSE
|
||||
- gulpfile.js
|
||||
- node_modules
|
||||
- '*.json'
|
||||
- package*.json
|
||||
|
||||
jekyll-archives:
|
||||
enabled: [categories, tags]
|
||||
@@ -173,6 +198,3 @@ jekyll-archives:
|
||||
permalinks:
|
||||
tag: /tags/:name/
|
||||
category: /categories/:name/
|
||||
|
||||
# Outdated configuration warning
|
||||
outdated: '-- Missing configuration options! --'
|
||||
|
||||
62
_data/assets/cross_origin.yml
Normal file
62
_data/assets/cross_origin.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
# CDNs
|
||||
|
||||
cdns:
|
||||
# Google Fonts
|
||||
- url: https://fonts.googleapis.com
|
||||
- url: https://fonts.gstatic.com
|
||||
args: crossorigin
|
||||
- url: https://fonts.googleapis.com
|
||||
# jsDelivr CDN
|
||||
- url: https://cdn.jsdelivr.net
|
||||
|
||||
# fonts
|
||||
|
||||
webfonts: https://fonts.googleapis.com/css2?family=Lato&family=Source+Sans+Pro:wght@400;600;700;900&display=swap
|
||||
|
||||
# Libraries
|
||||
|
||||
jquery:
|
||||
js: https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js
|
||||
|
||||
bootstrap:
|
||||
css: https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.bundle.min.js
|
||||
|
||||
bootstrap-toc:
|
||||
css: https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.css
|
||||
js: https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.js
|
||||
|
||||
fontawesome:
|
||||
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6/css/all.min.css
|
||||
|
||||
search:
|
||||
js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js
|
||||
|
||||
mermaid:
|
||||
js: https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.min.js
|
||||
|
||||
dayjs:
|
||||
js:
|
||||
common: https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js
|
||||
locale: https://cdn.jsdelivr.net/npm/dayjs@1/locale/:LOCALE.min.js
|
||||
relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1/plugin/relativeTime.min.js
|
||||
localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1/plugin/localizedFormat.min.js
|
||||
|
||||
countup:
|
||||
js: https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js
|
||||
|
||||
magnific-popup:
|
||||
css: https://cdn.jsdelivr.net/npm/magnific-popup@1/dist/magnific-popup.min.css
|
||||
js: https://cdn.jsdelivr.net/npm/magnific-popup@1/dist/jquery.magnific-popup.min.js
|
||||
|
||||
lozad:
|
||||
js: https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js
|
||||
|
||||
clipboard:
|
||||
js: https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js
|
||||
|
||||
polyfill:
|
||||
js: https://polyfill.io/v3/polyfill.min.js?features=es6
|
||||
|
||||
mathjax:
|
||||
js: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js
|
||||
51
_data/assets/self_host.yml
Normal file
51
_data/assets/self_host.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
# fonts
|
||||
|
||||
webfonts: /assets/lib/fonts/main.css
|
||||
|
||||
# Libraries
|
||||
|
||||
jquery:
|
||||
js: /assets/lib/jquery-3.6.0/jquery.min.js
|
||||
|
||||
bootstrap:
|
||||
css: /assets/lib/bootstrap-4.6.1/bootstrap.min.css
|
||||
js: /assets/lib/bootstrap-4.6.1/bootstrap.bundle.min.js
|
||||
|
||||
bootstrap-toc:
|
||||
css: /assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css
|
||||
js: /assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js
|
||||
|
||||
fontawesome:
|
||||
css: /assets/lib/fontawesome-free-6.2.1/css/all.min.css
|
||||
|
||||
search:
|
||||
js: /assets/lib/simple-jekyll-search-1.10.0/simple-jekyll-search.min.js
|
||||
|
||||
mermaid:
|
||||
js: /assets/lib/mermaid-9.1.7/mermaid.min.js
|
||||
|
||||
dayjs:
|
||||
js:
|
||||
common: /assets/lib/dayjs-1.10.7/dayjs.min.js
|
||||
locale: /assets/lib/dayjs-1.10.7/locale/en.min.js
|
||||
relativeTime: /assets/lib/dayjs-1.10.7/plugin/relativeTime.min.js
|
||||
localizedFormat: /assets/lib/dayjs-1.10.7/plugin/localizedFormat.min.js
|
||||
|
||||
countup:
|
||||
js: /assets/lib/countup.js-1.9.3/countUp.min.js
|
||||
|
||||
magnific-popup:
|
||||
css: /assets/lib/magnific-popup-1.1.0/magnific-popup.css
|
||||
js: /assets/lib/magnific-popup-1.1.0/jquery.magnific-popup.min.js
|
||||
|
||||
lozad:
|
||||
js: /assets/lib/lozad-1.16.0/lozad.min.js
|
||||
|
||||
clipboard:
|
||||
js: /assets/lib/clipboard-2.0.9/clipboard.min.js
|
||||
|
||||
polyfill:
|
||||
js: /assets/lib/polyfill-v3-es6/polyfill.min.js
|
||||
|
||||
mathjax:
|
||||
js: /assets/lib/mathjax-3.2.0/tex-chtml.js
|
||||
17
_data/authors.yml
Normal file
17
_data/authors.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
## Template › https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/advanced-usage.md#setting-author-url
|
||||
# -------------------------------------
|
||||
# {author_id}:
|
||||
# name: {full name}
|
||||
# twitter: {twitter_of_author}
|
||||
# url: {homepage_of_author}
|
||||
# -------------------------------------
|
||||
|
||||
cotes:
|
||||
name: Cotes Chung
|
||||
twitter: cotes2020
|
||||
url: https://github.com/cotes2020/
|
||||
|
||||
sille_bille:
|
||||
name: Dinesh Prasanth Moluguwan Krishnamoorthy
|
||||
twitter: dinesh_MKD
|
||||
url: https://github.com/SilleBille/
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
-
|
||||
type: github
|
||||
icon: 'fab fa-github-alt'
|
||||
icon: 'fab fa-github'
|
||||
-
|
||||
type: twitter
|
||||
icon: 'fab fa-twitter'
|
||||
|
||||
83
_data/locales/bg-BG.yml
Normal file
83
_data/locales/bg-BG.yml
Normal file
@@ -0,0 +1,83 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Публикация
|
||||
category: Категория
|
||||
tag: Тагове
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Начало
|
||||
categories: Категории
|
||||
tags: Тагове
|
||||
archives: Архив
|
||||
about: За мен
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: търси
|
||||
cancel: Отмени
|
||||
no_results: Упс! Не са намерени резултати.
|
||||
|
||||
panel:
|
||||
lastmod: Наскоро обновени
|
||||
trending_tags: Популярни тагове
|
||||
toc: Съдържание
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Тази публикация е лицензирана под :LICENSE_NAME от автора.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Някои права запазени.
|
||||
verbose: >-
|
||||
Освен ако не е посочено друго, публикациите в блога на този сайт са лицензирани
|
||||
под лиценза Creative Commons Attribution 4.0 (CC BY 4.0) от автора.
|
||||
|
||||
meta: Създадено чрез :PLATFORM и :THEME тема.
|
||||
|
||||
not_found:
|
||||
statment: Съжалявам, но този на този URL адрес няма налично съдържание.
|
||||
|
||||
notification:
|
||||
update_found: Налична е нова версия на съдържанието.
|
||||
update: Обнови
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Автор
|
||||
posted: Публикувана
|
||||
updated: Обновена
|
||||
words: думи
|
||||
pageview_measure: преглеждания
|
||||
read_time:
|
||||
unit: мин
|
||||
prompt: четиво
|
||||
relate_posts: Още за четене
|
||||
share: Споделете
|
||||
button:
|
||||
next: По-нови
|
||||
previous: По-стари
|
||||
copy_code:
|
||||
succeed: Копирано!
|
||||
share_link:
|
||||
title: Копирай линк
|
||||
succeed: Линкът е копиран успешно!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Прикрепен
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure:
|
||||
singular: категория
|
||||
plural: категории
|
||||
post_measure:
|
||||
singular: публикация
|
||||
plural: публикации
|
||||
82
_data/locales/de-DE.yml
Normal file
82
_data/locales/de-DE.yml
Normal file
@@ -0,0 +1,82 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Eintrag
|
||||
category: Kategorie
|
||||
tag: Tag
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Startseite
|
||||
categories: Kategorien
|
||||
tags: Tags
|
||||
archives: Archiv
|
||||
about: Über
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: Suche
|
||||
cancel: Abbrechen
|
||||
no_results: Ups! Keine Einträge gefunden.
|
||||
|
||||
panel:
|
||||
lastmod: Kürzlich aktualisiert
|
||||
trending_tags: Beliebte Tags
|
||||
toc: Inhalt
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Dieser Eintrag ist vom Autor unter :LICENSE_NAME lizensiert.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Einige Rechte vorbehalten.
|
||||
verbose: >-
|
||||
Alle Einträge auf dieser Seite stehen, soweit nicht anders angegeben, unter der Lizenz Creative Commons Attribution 4.0 (CC BY 4.0).
|
||||
|
||||
meta: Powered by :PLATFORM with :THEME theme.
|
||||
|
||||
not_found:
|
||||
statment: Entschuldigung, dieser Link verweist auf keine vorhandene Ressource.
|
||||
|
||||
notification:
|
||||
update_found: Eine neue Version ist verfügbar.
|
||||
update: Neue Version
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Von
|
||||
posted: Veröffentlicht
|
||||
updated: Aktualisiert
|
||||
words: Wörter
|
||||
pageview_measure: Aufrufe
|
||||
read_time:
|
||||
unit: Minuten
|
||||
prompt: lesen
|
||||
relate_posts: Weiterlesen
|
||||
share: Teilen
|
||||
button:
|
||||
next: Nächster Eintrag
|
||||
previous: Eintrag vorher
|
||||
copy_code:
|
||||
succeed: Kopiert!
|
||||
share_link:
|
||||
title: Link kopieren
|
||||
succeed: Link erfolgreich kopiert!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Angepinnt
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure:
|
||||
singular: Kategorie
|
||||
plural: Kategorien
|
||||
post_measure:
|
||||
singular: Eintrag
|
||||
plural: Einträge
|
||||
@@ -16,24 +16,17 @@ tabs:
|
||||
archives: Archives
|
||||
about: About
|
||||
|
||||
# text displayed in the search bar
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: search
|
||||
cancel: Cancel
|
||||
no_results: Oops! No results found.
|
||||
|
||||
panel:
|
||||
lastmod: Recent Update
|
||||
lastmod: Recently Updated
|
||||
trending_tags: Trending Tags
|
||||
toc: Contents
|
||||
|
||||
# The liquid date format › http://strftime.net/
|
||||
date_format:
|
||||
tooltip: '%a, %b %e, %Y, %l:%M %p %z'
|
||||
post:
|
||||
long: '%b %e, %Y'
|
||||
short: '%b %e'
|
||||
archive_month: '%b'
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
@@ -51,20 +44,17 @@ meta: Powered by :PLATFORM with :THEME theme.
|
||||
|
||||
not_found:
|
||||
statment: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
|
||||
hint_template: :HEAD_BAK to try finding it again, or search for it on the :ARCHIVES_PAGE.
|
||||
head_back: Head back Home
|
||||
archives_page: Archives page
|
||||
|
||||
notification:
|
||||
update_found: A new version of content is available.
|
||||
update: Update
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
published: 'on'
|
||||
written_by: By
|
||||
posted: Posted
|
||||
updated: Updated
|
||||
timeago:
|
||||
day: d ago
|
||||
hour: hr ago
|
||||
minute: min ago
|
||||
just_now: just now
|
||||
words: words
|
||||
pageview_measure: views
|
||||
read_time:
|
||||
@@ -75,13 +65,29 @@ post:
|
||||
button:
|
||||
next: Newer
|
||||
previous: Older
|
||||
copy:
|
||||
copy_code:
|
||||
succeed: Copied!
|
||||
share_link:
|
||||
title: Copy link
|
||||
succeed: Link copied successfully!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Pinned
|
||||
|
||||
# Date time format.
|
||||
# See: <http://strftime.net/>, <https://day.js.org/docs/en/display/format>
|
||||
df:
|
||||
post:
|
||||
strftime: '%b %e, %Y'
|
||||
dayjs: 'll'
|
||||
archives:
|
||||
strftime: '%b'
|
||||
dayjs: 'MMM'
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: categories
|
||||
post_measure: posts
|
||||
category_measure:
|
||||
singular: category
|
||||
plural: categories
|
||||
post_measure:
|
||||
singular: post
|
||||
plural: posts
|
||||
|
||||
79
_data/locales/es-ES.yml
Normal file
79
_data/locales/es-ES.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Entrada
|
||||
category: Categoría
|
||||
tag: Etiqueta
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Inicio
|
||||
categories: Categorías
|
||||
tags: Etiquetas
|
||||
archives: Archivo
|
||||
about: Acerca de
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: Buscar
|
||||
cancel: Cancelar
|
||||
no_results: ¡Oops! No se encuentran resultados.
|
||||
|
||||
panel:
|
||||
lastmod: Actualizado recientemente
|
||||
trending_tags: Etiquetas populares
|
||||
toc: Contenido
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Esta entrada está licenciada bajo :LICENSE_NAME por el autor.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Algunos derechos reservados.
|
||||
verbose: >-
|
||||
Salvo que se indique explícitamente, las entradas de este blog están licenciadas
|
||||
bajo la Creative Commons Attribution 4.0 International (CC BY 4.0) License por el autor.
|
||||
|
||||
meta: Hecho con :PLATFORM usando el tema :THEME.
|
||||
|
||||
not_found:
|
||||
statment: Lo sentimos, hemos perdido esa URL o apunta a algo que no existe.
|
||||
|
||||
notification:
|
||||
update_found: Hay una nueva versión de contenido disponible.
|
||||
update: Actualizar
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Por
|
||||
posted: Publicado
|
||||
updated: Actualizado
|
||||
words: palabras
|
||||
pageview_measure: visitas
|
||||
read_time:
|
||||
unit: min
|
||||
prompt: ' de lectura'
|
||||
relate_posts: Lecturas adicionales
|
||||
share: Compartir
|
||||
button:
|
||||
next: Nuevo
|
||||
previous: Anterior
|
||||
copy_code:
|
||||
succeed: ¡Copiado!
|
||||
share_link:
|
||||
title: Copiar enlace
|
||||
succeed: ¡Enlace copiado!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Fijado
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: categorias
|
||||
post_measure: entradas
|
||||
79
_data/locales/fr-FR.yml
Normal file
79
_data/locales/fr-FR.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Post
|
||||
category: Catégorie
|
||||
tag: Tag
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Accueil
|
||||
categories: Catégories
|
||||
tags: Tags
|
||||
archives: Archives
|
||||
about: A propos de
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: recherche
|
||||
cancel: Annuler
|
||||
no_results: Oups ! Aucun résultat trouvé.
|
||||
|
||||
panel:
|
||||
lastmod: Récemment mis à jour
|
||||
trending_tags: Tags tendance
|
||||
toc: Contenu
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Cet article est sous licence :LICENSE_NAME par l'auteur.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Certains droits réservés.
|
||||
verbose: >-
|
||||
Sauf mention contraire, les articles de ce site sont publiés sous licence
|
||||
sous la licence Creative Commons Attribution 4.0 International (CC BY 4.0) par l'auteur.
|
||||
|
||||
meta: Propulsé par :PLATFORM avec le thème :THEME
|
||||
|
||||
not_found:
|
||||
statment: Désolé, nous avons égaré cette URL ou elle pointe vers quelque chose qui n'existe pas.
|
||||
|
||||
notification:
|
||||
update_found: Une nouvelle version du contenu est disponible.
|
||||
update: Mise à jour
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Par
|
||||
posted: Posté
|
||||
updated: Mis à jour
|
||||
words: mots
|
||||
pageview_measure: vues
|
||||
read_time:
|
||||
unit: min
|
||||
prompt: lire
|
||||
relate_posts: Autres lectures
|
||||
share: Partager
|
||||
button:
|
||||
next: Plus récent
|
||||
previous: Plus ancien
|
||||
copy_code:
|
||||
succeed: Copié !
|
||||
share_link:
|
||||
title: Copier le lien
|
||||
succeed: Lien copié avec succès !
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Épinglé
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: catégories
|
||||
post_measure: posts
|
||||
81
_data/locales/hu-HU.yml
Normal file
81
_data/locales/hu-HU.yml
Normal file
@@ -0,0 +1,81 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Bejegyzés
|
||||
category: Kategória
|
||||
tag: Címke
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Kezdőlap
|
||||
categories: Kategóriák
|
||||
tags: Címkék
|
||||
archives: Archívum
|
||||
about: Rólam
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: keresés
|
||||
cancel: Mégse
|
||||
no_results: Oops! Nincs találat a keresésre.
|
||||
|
||||
panel:
|
||||
lastmod: Legutóbb frissítve
|
||||
trending_tags: Népszerű Címkék
|
||||
toc: Tartalom
|
||||
links: Blog linkek
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: A bejegyzés :LICENSE_NAME licenccel rendelkezik.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Néhány jog fenntartva.
|
||||
verbose: >-
|
||||
Az oldalon található tartalmak
|
||||
Creative Commons Attribution 4.0 International (CC BY 4.0) licenccel rendelkeznek,
|
||||
hacsak másképp nincs jelezve.
|
||||
|
||||
meta: Készítve :PLATFORM motorral :THEME témával.
|
||||
|
||||
not_found:
|
||||
statment: Sajnáljuk, az URL-t rosszul helyeztük el, vagy valami nem létezőre mutat.
|
||||
|
||||
notification:
|
||||
update_found: Elérhető a tartalom új verziója.
|
||||
update: Frissítés
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Szerző
|
||||
posted: Létrehozva
|
||||
updated: Frissítve
|
||||
words: szó
|
||||
pageview_measure: látogató
|
||||
read_time:
|
||||
unit: perc
|
||||
prompt: elolvasni
|
||||
relate_posts: További olvasnivaló
|
||||
share: Megosztás
|
||||
button:
|
||||
next: Újabb
|
||||
previous: Régebbi
|
||||
copy_code:
|
||||
succeed: Másolva!
|
||||
share_link:
|
||||
title: Link másolása
|
||||
succeed: Link sikeresen másolva!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Kitűzve
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: kategória
|
||||
post_measure: bejegyzés
|
||||
79
_data/locales/id-ID.yml
Normal file
79
_data/locales/id-ID.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Postingan
|
||||
category: Kategori
|
||||
tag: Tagar
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Beranda
|
||||
categories: Kategori
|
||||
tags: Tagar
|
||||
archives: Arsip
|
||||
about: Tentang
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: Cari
|
||||
cancel: Batal
|
||||
no_results: Ups! Tidak ada hasil yang ditemukan.
|
||||
|
||||
panel:
|
||||
lastmod: Postingan Terbaru
|
||||
trending_tags: Tagar Terpopuler
|
||||
toc: Konten
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Postingan ini dilisensikan di bawah :LICENSE_NAME oleh penulis.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Sebagian konten dilindungi.
|
||||
verbose: >-
|
||||
Kecuali jika dinyatakan, Postingan blog di situs ini dilisensikan
|
||||
di bawah Lisensi Creative Commons Attribution 4.0 International (CC BY 4.0) oleh penulis.
|
||||
|
||||
meta: Didukung oleh :PLATFORM dengan tema :THEME.
|
||||
|
||||
not_found:
|
||||
statment: Maaf, kami gagal menemukan URL itu atau memang mengarah ke sesuatu yang tidak ada.
|
||||
|
||||
notification:
|
||||
update_found: Versi konten baru tersedia.
|
||||
update: Perbarui
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Oleh
|
||||
posted: Diterbitkan
|
||||
updated: Diperbarui
|
||||
words: kata
|
||||
pageview_measure: dilihat
|
||||
read_time:
|
||||
unit: menit
|
||||
prompt: baca
|
||||
relate_posts: Postingan Lainya
|
||||
share: Bagikan
|
||||
button:
|
||||
next: Terbaru
|
||||
previous: Terlama
|
||||
copy_code:
|
||||
succeed: Disalin!
|
||||
share_link:
|
||||
title: Salin tautan
|
||||
succeed: Tautan berhasil disalin!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Disematkan
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: kategori
|
||||
post_measure: Postingan
|
||||
86
_data/locales/ko-KR.yml
Normal file
86
_data/locales/ko-KR.yml
Normal file
@@ -0,0 +1,86 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: 포스트
|
||||
category: 카테고리
|
||||
tag: 태그
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: 홈
|
||||
categories: 카테고리
|
||||
tags: 태그
|
||||
archives: 아카이브
|
||||
about: 정보
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: 검색
|
||||
cancel: 취소
|
||||
no_results: 검색 결과가 없습니다.
|
||||
|
||||
panel:
|
||||
lastmod: 최근 업데이트
|
||||
trending_tags: 인기 태그
|
||||
toc: 바로가기
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: 이 기사는 저작권자의 :LICENSE_NAME 라이센스를 따릅니다.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: 일부 권리 보유
|
||||
verbose: >-
|
||||
명시되지 않는 한 이 사이트의 블로그 게시물은 작성자의
|
||||
Creative Commons Attribution 4.0 International(CC BY 4.0) 라이선스에 따라 사용이 허가되었습니다.
|
||||
|
||||
meta: Powered by :PLATFORM with :THEME theme.
|
||||
|
||||
not_found:
|
||||
statment: 해당 URL은 존재하지 않습니다.
|
||||
|
||||
notification:
|
||||
update_found: 새 버전의 콘텐츠를 사용할 수 있습니다.
|
||||
update: 업데이트
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: By
|
||||
posted: 게시
|
||||
updated: 업데이트
|
||||
words: 단어
|
||||
pageview_measure: 조회
|
||||
read_time:
|
||||
unit: 분
|
||||
prompt: 읽는 시간
|
||||
relate_posts: 관련된 글
|
||||
share: 공유하기
|
||||
button:
|
||||
next: 다음 글
|
||||
previous: 이전 글
|
||||
copy_code:
|
||||
succeed: 복사되었습니다!
|
||||
share_link:
|
||||
title: 링크 복사하기
|
||||
succeed: 링크가 복사되었습니다!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: 핀
|
||||
|
||||
# Date time format.
|
||||
# See: <http://strftime.net/>, <https://day.js.org/docs/en/display/format>
|
||||
df:
|
||||
post:
|
||||
strftime: '%Y/%m/%d'
|
||||
dayjs: 'YYYY/MM/DD'
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: 카테고리
|
||||
post_measure: 포스트
|
||||
79
_data/locales/my-MM.yml
Normal file
79
_data/locales/my-MM.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: ပို့စ်
|
||||
category: ကဏ္ဍ
|
||||
tag: နာမ(တက်ဂ်)
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: အဓိကစာမျက်နှာ
|
||||
categories: ကဏ္ဍများ
|
||||
tags: နာမ(တက်ဂ်)များ
|
||||
archives: မှတ်တမ်းတိုက်
|
||||
about: အကြောင်းအရာ
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: ရှာဖွေမည်
|
||||
cancel: ဖျက်သိမ်းမည်
|
||||
no_results: အိုး! ဘာမှမရှိပါ
|
||||
|
||||
panel:
|
||||
lastmod: မကြာသေးမီကမွမ်းမံထားသည်
|
||||
trending_tags: ခေတ်စားနေသည့်တက်ဂ်များ
|
||||
toc: အကြောင်းအရာများ
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: ဤပို့စ်သည်စာရေးသူ၏ :LICENSE_NAME လိုင်စင်ရထားသည်။
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: မူပိုင်ခွင့်အချို့ကို လက်ဝယ်ထားသည်။
|
||||
verbose: >-
|
||||
အခြားမှတ်သားထားချက်များမှလွဲ၍ ဤဆိုက်ရှိ ဘလော့ဂ်ပို့စ်များသည် စာရေးသူ၏
|
||||
Creative Commons Attribution 4.0 International (CC BY 4.0) အောက်တွင် လိုင်စင်ရထားပါသည်။
|
||||
|
||||
meta: Powered by :PLATFORM with :THEME theme.
|
||||
|
||||
not_found:
|
||||
statment: ဝမ်းနည်းပါသည်၊ ကျွန်ုပ်တို့သည် အဆိုပါ URL ကို မှားယွင်းစွာ နေရာချထားခြင်း သို့မဟုတ် ၎င်းသည် မရှိသောအရာကို ညွှန်ပြနေပါသည်။
|
||||
|
||||
notification:
|
||||
update_found: အကြောင်းအရာဗားရှင်းအသစ်ကို ရနိုင်ပါပြီ။
|
||||
update: အပ်ဒိတ်
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: ကရေးသားခဲ့သည်။
|
||||
posted: တင်ထားခဲ့သည်။
|
||||
updated: မွမ်းမံထားခဲ့သည်။
|
||||
words: စကားလုံးများ
|
||||
pageview_measure: အမြင်များ
|
||||
read_time:
|
||||
unit: မိနစ်
|
||||
prompt: ဖတ်ပါမည်
|
||||
relate_posts: နောက်ထပ်ဖတ်ရန်
|
||||
share: မျှဝေရန်
|
||||
button:
|
||||
next: အသစ်များ
|
||||
previous: အဟောင်းများ
|
||||
copy_code:
|
||||
succeed: ကူးယူလိုက်ပြီ။
|
||||
share_link:
|
||||
title: လင့်ခ်ကို ကူးယူရန်
|
||||
succeed: လင့်ခ်ကို ကူးယူလိုက်ပြီ။
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: ချိတ်ထားသည်။
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: ကဏ္ဍများ
|
||||
post_measure: ပို့စ်များ
|
||||
79
_data/locales/pt-BR.yml
Normal file
79
_data/locales/pt-BR.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Post
|
||||
category: Categoria
|
||||
tag: Tag
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Home
|
||||
categories: Categorias
|
||||
tags: Tags
|
||||
archives: Arquivos
|
||||
about: Sobre
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: Buscar
|
||||
cancel: Cancelar
|
||||
no_results: Oops! Nenhum resultado encontrado.
|
||||
|
||||
panel:
|
||||
lastmod: Atualizados recentemente
|
||||
trending_tags: Trending Tags
|
||||
toc: Conteúdo
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Esta postagem está licenciada sob :LICENSE_NAME pelo autor.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Alguns direitos reservados.
|
||||
verbose: >-
|
||||
Exceto onde indicado de outra forma, as postagens do blog neste site são licenciadas sob a
|
||||
Creative Commons Attribution 4.0 International (CC BY 4.0) License pelo autor.
|
||||
|
||||
meta: Feito com :PLATFORM usando o tema :THEME.
|
||||
|
||||
not_found:
|
||||
statment: Desculpe, a página não foi encontrada.
|
||||
|
||||
notification:
|
||||
update_found: Uma nova versão do conteúdo está disponível.
|
||||
update: atualização
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Por
|
||||
posted: Postado em
|
||||
updated: Atualizado
|
||||
words: palavras
|
||||
pageview_measure: visualizações
|
||||
read_time:
|
||||
unit: min
|
||||
prompt: " de leitura"
|
||||
relate_posts: Leia também
|
||||
share: Compartilhar
|
||||
button:
|
||||
next: Próximo
|
||||
previous: Anterior
|
||||
copy_code:
|
||||
succeed: Copiado!
|
||||
share_link:
|
||||
title: Copie o link
|
||||
succeed: Link copiado com sucesso!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Fixado
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: categorias
|
||||
post_measure: posts
|
||||
79
_data/locales/ru-RU.yml
Normal file
79
_data/locales/ru-RU.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Публикация
|
||||
category: Категория
|
||||
tag: Тег
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Домашняя страница
|
||||
categories: Категории
|
||||
tags: Теги
|
||||
archives: Архив
|
||||
about: О сайте
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: поиск
|
||||
cancel: Отменить
|
||||
no_results: Ох! Ничего не найдено.
|
||||
|
||||
panel:
|
||||
lastmod: Недавно обновлено
|
||||
trending_tags: Популярные теги
|
||||
toc: Содержание
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Публикация защищена лицензией :LICENSE_NAME.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Некоторые права защищены.
|
||||
verbose: >-
|
||||
Публикации на сайте защищены лицензией Creative Commons Attribution 4.0 International (CC BY 4.0),
|
||||
если в тексте публикации не указано иное.
|
||||
|
||||
meta: Powered by :PLATFORM with :THEME theme.
|
||||
|
||||
not_found:
|
||||
statment: Извините, эта ссылка указывает на ресурс который не существует.
|
||||
|
||||
notification:
|
||||
update_found: Доступна новая версия контента.
|
||||
update: Обновлять
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Автор
|
||||
posted: Время публикации
|
||||
updated: Обновлено
|
||||
words: слов
|
||||
pageview_measure: просмотров
|
||||
read_time:
|
||||
unit: минут
|
||||
prompt: чтения
|
||||
relate_posts: Вам также может быть интересно
|
||||
share: Поделиться
|
||||
button:
|
||||
next: Предыдущая публикация
|
||||
previous: Следующая публикация
|
||||
copy_code:
|
||||
succeed: Скопировано успешно!
|
||||
share_link:
|
||||
title: Скопировать ссылку
|
||||
succeed: Ссылка успешно скопирована!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Закреплено
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: категории
|
||||
post_measure: публикации
|
||||
79
_data/locales/tr-TR.yml
Normal file
79
_data/locales/tr-TR.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Gönderi
|
||||
category: Kategori
|
||||
tag: Etiket
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Ana Sayfa
|
||||
categories: Kategoriler
|
||||
tags: Etiketler
|
||||
archives: Arşiv
|
||||
about: Hakkında
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: Ara...
|
||||
cancel: İptal
|
||||
no_results: Hop! Öyle bir şey bulamadım.
|
||||
|
||||
panel:
|
||||
lastmod: Yeni Güncellendi
|
||||
trending_tags: Yükselen Etiketler
|
||||
toc: İçindekiler
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Bu gönderi :LICENSE_NAME lisansı altındadır.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/deed.tr
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Bazı hakları saklıdır.
|
||||
verbose: >-
|
||||
Aksi belirtilmediği sürece, bu sitedeki gönderiler Creative Commons Atıf 4.0 Uluslararası (CC BY 4.0) Lisansı altındadır.
|
||||
Kısaca sayfa linkini de vererek paylaşabilir veya düzenleyip paylaşabilirsin.
|
||||
|
||||
meta: :PLATFORM ve :THEME teması.
|
||||
|
||||
not_found:
|
||||
statment: Üzgünüz, bu linki yanlış yerleştirdik veya var olmayan bir şeye işaret ediyor.
|
||||
|
||||
notification:
|
||||
update_found: İçeriğin yeni bir sürümü mevcut.
|
||||
update: Güncelle
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Yazan
|
||||
posted: Gönderilme Tarihi
|
||||
updated: Güncellenme Tarihi
|
||||
words: sözcük
|
||||
pageview_measure: görüntülenme
|
||||
read_time:
|
||||
unit: dakikada
|
||||
prompt: okunabilir
|
||||
relate_posts: Benzer Gönderiler
|
||||
share: Paylaş
|
||||
button:
|
||||
next: İleri
|
||||
previous: Geri
|
||||
copy_code:
|
||||
succeed: Kopyalandı.
|
||||
share_link:
|
||||
title: Linki kopyala
|
||||
succeed: Link kopyalandı.
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Sabitlendi
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: kategori
|
||||
post_measure: gönderi
|
||||
79
_data/locales/uk-UA.yml
Normal file
79
_data/locales/uk-UA.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Публікація
|
||||
category: Категорія
|
||||
tag: Тег
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Домашня сторінка
|
||||
categories: Категорії
|
||||
tags: Теги
|
||||
archives: Архів
|
||||
about: Про сайт
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: пошук
|
||||
cancel: Скасувати
|
||||
no_results: Ох! Нічого не знайдено.
|
||||
|
||||
panel:
|
||||
lastmod: Нещодавно оновлено
|
||||
trending_tags: Популярні теги
|
||||
toc: Зміст
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Публікація захищена ліцензією :LICENSE_NAME.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Деякі права захищено.
|
||||
verbose: >-
|
||||
Публікації на сайті захищено ліцензією Creative Commons Attribution 4.0 International (CC BY 4.0),
|
||||
якщо інше не вказано в тексті.
|
||||
|
||||
meta: Powered by :PLATFORM with :THEME theme.
|
||||
|
||||
not_found:
|
||||
statment: Вибачте, це посилання вказує на ресурс, що не існує.
|
||||
|
||||
notification:
|
||||
update_found: Доступна нова версія вмісту.
|
||||
update: Оновлення
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Автор
|
||||
posted: Час публікації
|
||||
updated: Оновлено
|
||||
words: слів
|
||||
pageview_measure: переглядів
|
||||
read_time:
|
||||
unit: хвилин
|
||||
prompt: читання
|
||||
relate_posts: Вас також може зацікавити
|
||||
share: Поділитися
|
||||
button:
|
||||
next: Попередня публікація
|
||||
previous: Наступна публікація
|
||||
copy_code:
|
||||
succeed: Успішно скопійовано!
|
||||
share_link:
|
||||
title: Скопіювати посилання
|
||||
succeed: Посилання успішно скопійовано!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Закріплено
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: категорії
|
||||
post_measure: публікації
|
||||
77
_data/locales/vi-VN.yml
Normal file
77
_data/locales/vi-VN.yml
Normal file
@@ -0,0 +1,77 @@
|
||||
# The layout text of site
|
||||
|
||||
# ----- Commons label -----
|
||||
|
||||
layout:
|
||||
post: Bài viết
|
||||
category: Danh mục
|
||||
tag: Thẻ
|
||||
|
||||
# The tabs of sidebar
|
||||
tabs:
|
||||
# format: <filename_without_extension>: <value>
|
||||
home: Trang chủ
|
||||
categories: Các danh mục
|
||||
tags: Các thẻ
|
||||
archives: Lưu trữ
|
||||
about: Giới thiệu
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: tìm kiếm
|
||||
cancel: Hủy
|
||||
no_results: Không có kết quả tìm kiếm.
|
||||
|
||||
panel:
|
||||
lastmod: Mới cập nhật
|
||||
trending_tags: Các thẻ thịnh hành
|
||||
toc: Mục lục
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: Bài viết này được cấp phép bởi tác giả theo giấy phép :LICENSE_NAME.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Một số quyền được bảo lưu.
|
||||
verbose: >-
|
||||
Trừ khi có ghi chú khác, các bài viết đăng trên trang này được cấp phép bởi tác giả theo giấy phép Creative Commons Attribution 4.0 International (CC BY 4.0).
|
||||
meta: Trang web này được tạo bởi :PLATFORM với chủ đề :THEME.
|
||||
|
||||
not_found:
|
||||
statment: Xin lỗi, chúng tôi đã đặt nhầm URL hoặc đường dẫn trỏ đến một trang nào đó không tồn tại.
|
||||
|
||||
notification:
|
||||
update_found: Đã có phiên bản mới của nội dung.
|
||||
update: Cập nhật
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
written_by: Viết bởi
|
||||
posted: Đăng lúc
|
||||
updated: Cập nhật lúc
|
||||
words: từ
|
||||
pageview_measure: lượt xem
|
||||
read_time:
|
||||
unit: phút
|
||||
prompt: đọc
|
||||
relate_posts: Bài viết liên quan
|
||||
share: Chia sẻ
|
||||
button:
|
||||
next: Mới hơn
|
||||
previous: Cũ hơn
|
||||
copy_code:
|
||||
succeed: Đã sao chép!
|
||||
share_link:
|
||||
title: Sao chép đường dẫn
|
||||
succeed: Đã sao chép đường dẫn thành công!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: Bài ghim
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: danh mục
|
||||
post_measure: bài viết
|
||||
@@ -16,23 +16,16 @@ tabs:
|
||||
archives: 归档
|
||||
about: 关于
|
||||
|
||||
# text displayed in the search bar
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: 搜索
|
||||
cancel: 取消
|
||||
no_results: 搜索结果为空
|
||||
|
||||
panel:
|
||||
lastmod: 最近更新
|
||||
trending_tags: 热门标签
|
||||
toc: 目录
|
||||
|
||||
# The liquid date format › http://strftime.net/
|
||||
date_format:
|
||||
tooltip: '%a, %F, %R %z'
|
||||
post:
|
||||
long: '%F'
|
||||
short: '%m-%d'
|
||||
archive_month: '%m月'
|
||||
toc: 文章内容
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
@@ -50,20 +43,17 @@ meta: 本站由 :PLATFORM 生成,采用 :THEME 主题。
|
||||
|
||||
not_found:
|
||||
statment: 抱歉,我们放错了该 URL,或者它指向了不存在的内容。
|
||||
hint_template: :HEAD_BAK尝试再次查找它,或在:ARCHIVES_PAGE上搜索它。
|
||||
head_back: 返回主页
|
||||
archives_page: 归档页面
|
||||
|
||||
notification:
|
||||
update_found: 发现新版本的内容。
|
||||
update: 更新
|
||||
|
||||
# ----- Posts related labels -----
|
||||
|
||||
post:
|
||||
published: 发表于
|
||||
written_by: 作者
|
||||
posted: 发表于
|
||||
updated: 更新于
|
||||
timeago:
|
||||
day: 天前
|
||||
hour: 小时前
|
||||
minute: 分钟前
|
||||
just_now: 刚刚
|
||||
words: 字
|
||||
pageview_measure: 次浏览
|
||||
read_time:
|
||||
@@ -74,12 +64,21 @@ post:
|
||||
button:
|
||||
next: 下一篇
|
||||
previous: 上一篇
|
||||
copy:
|
||||
copy_code:
|
||||
succeed: 已复制!
|
||||
share_link:
|
||||
title: 分享链接
|
||||
succeed: 链接已复制!
|
||||
# pinned prompt of posts list on homepage
|
||||
pin_prompt: 顶置
|
||||
|
||||
# Date time format.
|
||||
# See: <http://strftime.net/>, <https://day.js.org/docs/en/display/format>
|
||||
df:
|
||||
post:
|
||||
strftime: '%Y/%m/%d'
|
||||
dayjs: 'YYYY/MM/DD'
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: 个分类
|
||||
|
||||
@@ -13,7 +13,7 @@ platforms:
|
||||
-
|
||||
type: Telegram
|
||||
icon: "fab fa-telegram"
|
||||
link: "https://telegram.me/share?text=TITLE&url=URL"
|
||||
link: "https://t.me/share/url?url=URL&text=TITLE"
|
||||
|
||||
# Uncomment below if you need to.
|
||||
# -
|
||||
|
||||
12
_includes/assets-origin.html
Normal file
12
_includes/assets-origin.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{% comment %} Site static assets origin {% endcomment %}
|
||||
{% assign origin = 'cross_origin' %}
|
||||
|
||||
{% if site.assets.self_host.enabled %}
|
||||
{% if site.assets.self_host.env %}
|
||||
{% if site.assets.self_host.env == jekyll.environment %}
|
||||
{% assign origin = 'self_host' %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% assign origin = 'self_host' %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
5
_includes/comments.html
Normal file
5
_includes/comments.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<!-- The comments switcher -->
|
||||
{% if page.comments and site.comments.active %}
|
||||
{% capture path %}comments/{{ site.comments.active }}.html{% endcapture %}
|
||||
{% include {{ path }} %}
|
||||
{% endif %}
|
||||
54
_includes/comments/disqus.html
Normal file
54
_includes/comments/disqus.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<!--
|
||||
The Disqus lazy loading.
|
||||
-->
|
||||
<div id="disqus_thread" class="pt-2 pb-2">
|
||||
<p class="text-center text-muted small">
|
||||
Comments powered by <a href="https://disqus.com/">Disqus</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
var disqus_config = function () {
|
||||
this.page.url = '{{ page.url | absolute_url }}';
|
||||
this.page.identifier = '{{ page.url }}';
|
||||
};
|
||||
|
||||
/* Lazy loading */
|
||||
var disqus_observer = new IntersectionObserver(function (entries) {
|
||||
if(entries[0].isIntersecting) {
|
||||
(function () {
|
||||
var d = document, s = d.createElement('script');
|
||||
s.src = 'https://{{ site.comments.disqus.shortname }}.disqus.com/embed.js';
|
||||
s.setAttribute('data-timestamp', +new Date());
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
|
||||
disqus_observer.disconnect();
|
||||
}
|
||||
}, { threshold: [0] });
|
||||
|
||||
disqus_observer.observe(document.querySelector('#disqus_thread'));
|
||||
|
||||
/* Auto switch theme */
|
||||
function reloadDisqus() {
|
||||
if (event.source === window && event.data &&
|
||||
event.data.direction === ModeToggle.ID) {
|
||||
/* Disqus hasn't been loaded */
|
||||
if (typeof DISQUS === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.readyState == 'complete') {
|
||||
DISQUS.reset({ reload: true, config: disqus_config });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const modeToggle = document.querySelector(".mode-toggle");
|
||||
|
||||
if (typeof modeToggle !== "undefined") {
|
||||
window.addEventListener("message", reloadDisqus);
|
||||
}
|
||||
|
||||
</script>
|
||||
56
_includes/comments/giscus.html
Normal file
56
_includes/comments/giscus.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<!-- https://giscus.app/ -->
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
const origin = "https://giscus.app";
|
||||
const iframe = "iframe.giscus-frame";
|
||||
const lightTheme = "light";
|
||||
const darkTheme = "dark_dimmed";
|
||||
let initTheme = lightTheme;
|
||||
|
||||
if ($("html[data-mode=dark]").length > 0
|
||||
|| ($("html[data-mode]").length == 0
|
||||
&& window.matchMedia("(prefers-color-scheme: dark)").matches)) {
|
||||
initTheme = darkTheme;
|
||||
}
|
||||
|
||||
let giscusAttributes = {
|
||||
"src": "https://giscus.app/client.js",
|
||||
"data-repo": "{{ site.comments.giscus.repo}}",
|
||||
"data-repo-id": "{{ site.comments.giscus.repo_id }}",
|
||||
"data-category": "{{ site.comments.giscus.category }}",
|
||||
"data-category-id": "{{ site.comments.giscus.category_id }}",
|
||||
"data-mapping": "{{ site.comments.giscus.mapping | default: 'pathname' }}",
|
||||
"data-reactions-enabled": "{{ site.comments.giscus.reactions_enabled | default: '1' }}",
|
||||
"data-emit-metadata": "0",
|
||||
"data-theme": initTheme,
|
||||
"data-input-position": "{{ site.comments.giscus.input_position | default: 'bottom' }}",
|
||||
"data-lang": "{{ site.comments.giscus.lang | default: lang }}",
|
||||
"crossorigin": "anonymous",
|
||||
"async": ""
|
||||
};
|
||||
|
||||
let giscusScript = document.createElement("script");
|
||||
Object.entries(giscusAttributes).forEach(([key, value]) => giscusScript.setAttribute(key, value));
|
||||
document.getElementById("tail-wrapper").appendChild(giscusScript);
|
||||
|
||||
addEventListener("message", (event) => {
|
||||
if (event.source === window && event.data &&
|
||||
event.data.direction === ModeToggle.ID) {
|
||||
/* global theme mode changed */
|
||||
const mode = event.data.message;
|
||||
const theme = (mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme);
|
||||
|
||||
const message = {
|
||||
setConfig: {
|
||||
theme: theme
|
||||
}
|
||||
};
|
||||
|
||||
const giscus = document.querySelector(iframe).contentWindow;
|
||||
giscus.postMessage({ giscus: message }, origin);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
51
_includes/comments/utterances.html
Normal file
51
_includes/comments/utterances.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<!-- https://utteranc.es/ -->
|
||||
<script src="https://utteranc.es/client.js"
|
||||
repo="{{ site.comments.utterances.repo }}"
|
||||
issue-term="{{ site.comments.utterances.issue_term }}"
|
||||
crossorigin="anonymous"
|
||||
async>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
const origin = "https://utteranc.es";
|
||||
const iframe = "iframe.utterances-frame";
|
||||
const lightTheme = "github-light";
|
||||
const darkTheme = "github-dark";
|
||||
let initTheme = lightTheme;
|
||||
|
||||
if ($("html[data-mode=dark]").length > 0
|
||||
|| ($("html[data-mode]").length == 0
|
||||
&& window.matchMedia("(prefers-color-scheme: dark)").matches)) {
|
||||
initTheme = darkTheme;
|
||||
}
|
||||
|
||||
addEventListener("message", (event) => {
|
||||
let theme;
|
||||
|
||||
/* credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347> */
|
||||
if (event.origin === origin) {
|
||||
/* page initial */
|
||||
theme = initTheme;
|
||||
|
||||
} else if (event.source === window && event.data &&
|
||||
event.data.direction === ModeToggle.ID) {
|
||||
/* global theme mode changed */
|
||||
const mode = event.data.message;
|
||||
theme = (mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme);
|
||||
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
const message = {
|
||||
type: "set-theme",
|
||||
theme: theme
|
||||
};
|
||||
|
||||
const utterances = document.querySelector(iframe).contentWindow;
|
||||
utterances.postMessage(message, origin);
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
@@ -1,15 +0,0 @@
|
||||
<!--
|
||||
CSS selector for site.
|
||||
-->
|
||||
|
||||
<link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}">
|
||||
|
||||
{% if site.toc and page.toc %}
|
||||
<link rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.css">
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'page' or page.layout == 'post' %}
|
||||
<!-- Manific Popup -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/magnific-popup.min.css">
|
||||
{% endif %}
|
||||
15
_includes/datetime.html
Normal file
15
_includes/datetime.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!--
|
||||
Date format snippet
|
||||
See: ${JS_ROOT}/utils/locale-dateime.js
|
||||
-->
|
||||
|
||||
{% assign wrap_elem = include.wrap | default: 'em' %}
|
||||
{% assign df_strftime = site.data.locales[site.lang].df.post.strftime | default: '%d/%m/%Y' %}
|
||||
{% assign df_dayjs = site.data.locales[site.lang].df.post.dayjs | default: 'DD/MM/YYYY' %}
|
||||
|
||||
<{{ wrap_elem }} class="{% if include.class %}{{ include.class }}{% endif %}"
|
||||
data-ts="{{ include.date | date: '%s' }}"
|
||||
data-df="{{ df_dayjs }}"
|
||||
{% if include.tooltip %}data-toggle="tooltip" data-placement="bottom"{% endif %}>
|
||||
{{ include.date | date: df_strftime }}
|
||||
</{{ wrap_elem }}>
|
||||
@@ -1,25 +0,0 @@
|
||||
<!--
|
||||
The Disqus lazy loading.
|
||||
Powered by: <https://github.com/osvaldasvalutis/disqusLoader.js>
|
||||
-->
|
||||
|
||||
<div id="disqus" class="pt-2 pb-2">
|
||||
<p class="text-center text-muted small pb-5">
|
||||
Comments powered by <a href="https://disqus.com/">Disqus</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script src="{{ '/assets/js/lib/jquery.disqusloader.min.js' | relative_url }}"></script>
|
||||
<script>
|
||||
const options = {
|
||||
scriptUrl: '//{{ site.disqus.shortname }}.disqus.com/embed.js',
|
||||
|
||||
disqusConfig: function() {
|
||||
this.page.title = '{{ page.title }}';
|
||||
this.page.url = '{{ page.url | absolute_url }}';
|
||||
this.page.identifier = '{{ page.url }}';
|
||||
}
|
||||
};
|
||||
|
||||
$.disqusLoader('#disqus', options);
|
||||
</script>
|
||||
@@ -1,39 +1,36 @@
|
||||
<!--
|
||||
The Footer
|
||||
-->
|
||||
<!-- The Footer -->
|
||||
|
||||
<footer class="d-flex w-100 justify-content-center">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="footer-left">
|
||||
<p class="mb-0">
|
||||
© {{ 'now' | date: "%Y" }}
|
||||
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
|
||||
{% if site.data.locales[site.lang].copyright.brief %}
|
||||
<span data-toggle="tooltip" data-placement="top"
|
||||
title="{{ site.data.locales[site.lang].copyright.verbose }}">{{ site.data.locales[site.lang].copyright.brief }}</span>
|
||||
{% else %}
|
||||
<span class="text-muted">{{ site.outdated }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<footer>
|
||||
<div class="container pl-lg-4 pr-lg-4">
|
||||
<div class="d-flex justify-content-between align-items-center text-muted ml-md-3 mr-md-3">
|
||||
<div class="footer-left">
|
||||
<p class="mb-0">
|
||||
© {{ 'now' | date: "%Y" }}
|
||||
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
|
||||
{% if site.data.locales[site.lang].copyright.brief %}
|
||||
<span data-toggle="tooltip" data-placement="top"
|
||||
title="{{ site.data.locales[site.lang].copyright.verbose }}">{{ site.data.locales[site.lang].copyright.brief }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="footer-right">
|
||||
<p class="mb-0">
|
||||
{% capture _platform %}
|
||||
<div class="footer-right">
|
||||
<p class="mb-0">
|
||||
|
||||
{% capture _platform %}
|
||||
<a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>
|
||||
{% endcapture %}
|
||||
{% endcapture %}
|
||||
|
||||
{% capture _theme %}
|
||||
{% capture _theme %}
|
||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener">Chirpy</a>
|
||||
{% endcapture %}
|
||||
{% endcapture %}
|
||||
|
||||
{{ site.data.locales[site.lang].meta
|
||||
| default: 'Powered by :PLATFORM with :THEME theme.'
|
||||
| replace: ':PLATFORM', _platform | replace: ':THEME', _theme
|
||||
}}
|
||||
|
||||
</p>
|
||||
{{ site.data.locales[site.lang].meta
|
||||
| default: 'Powered by :PLATFORM with :THEME theme.'
|
||||
| replace: ':PLATFORM', _platform | replace: ':THEME', _theme
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- div.d-flex -->
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -8,13 +8,6 @@
|
||||
|
||||
{% if page.layout == 'home' or page.layout == 'post' %}
|
||||
|
||||
<!-- i18n for timeago.js -->
|
||||
<meta name="layout-lang" content="{{ site.lang | default: "en" }}">
|
||||
<meta name="day-prompt" content="{{ site.data.locales[site.lang].post.timeago.day | default: "d ago" }}">
|
||||
<meta name="hour-prompt" content="{{ site.data.locales[site.lang].post.timeago.hour | default: "hr ago" }}">
|
||||
<meta name="minute-prompt" content="{{ site.data.locales[site.lang].post.timeago.minute | default: "min ago" }}">
|
||||
<meta name="justnow-prompt" content="{{ site.data.locales[site.lang].post.timeago.just_now | default: "just now" }}">
|
||||
|
||||
{% if site.google_analytics.pv.proxy_endpoint %}
|
||||
<meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}">
|
||||
{% endif %}
|
||||
@@ -25,7 +18,29 @@
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% seo title=false %}
|
||||
{% capture seo_tags %}
|
||||
{% seo title=false %}
|
||||
{% endcapture %}
|
||||
|
||||
{% if page.image %}
|
||||
{% assign img = page.image.path | default: page.image %}
|
||||
{% assign img_path = page.img_path | append: '/' | append: img | replace: '//', '/' %}
|
||||
{% capture target %}"{{ img | absolute_url }}"{% endcapture %}
|
||||
|
||||
{% if site.img_cdn contains '//' %}
|
||||
<!-- it's a cross-origin URL -->
|
||||
{% capture replacement %}"{{ site.img_cdn }}{{ img_path }}"{% endcapture %}
|
||||
{% else %}
|
||||
<!-- it's a local file path -->
|
||||
{%- capture replacement -%}
|
||||
"{{ site.img_cdn | append: '/' | append: img_path | replace: '//', '/' | absolute_url }}"
|
||||
{%- endcapture -%}
|
||||
{% endif %}
|
||||
|
||||
{% assign seo_tags = seo_tags | replace: target, replacement %}
|
||||
{% endif %}
|
||||
|
||||
{{ seo_tags }}
|
||||
|
||||
<title>
|
||||
{%- unless page.layout == "home" -%}
|
||||
@@ -36,12 +51,24 @@
|
||||
|
||||
{% include favicons.html %}
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous">
|
||||
<link rel="dns-prefetch" href="https://fonts.gstatic.com">
|
||||
{% if site.resources.ignore_env != jekyll.environment and site.resources.self_hosted %}
|
||||
|
||||
<link href="{{ site.data.assets[origin].webfonts | relative_url }}" rel="stylesheet">
|
||||
|
||||
{% else %}
|
||||
|
||||
{% for cdn in site.data.assets[origin].cdns %}
|
||||
<link rel="preconnect" href="{{ cdn.url }}" {{ cdn.args }}>
|
||||
<link rel="dns-prefetch" href="{{ cdn.url }}" {{ cdn.args }}>
|
||||
{% endfor %}
|
||||
|
||||
<link rel="stylesheet" href="{{ site.data.assets[origin].webfonts | relative_url }}">
|
||||
|
||||
{% endif %}
|
||||
|
||||
<!-- GA -->
|
||||
{% if jekyll.environment == 'production' %}
|
||||
{% if jekyll.environment == 'production'
|
||||
and site.google_analytics.id != empty and site.google_analytics.id %}
|
||||
<link rel="preconnect" href="https://www.google-analytics.com" crossorigin="use-credentials">
|
||||
<link rel="dns-prefetch" href="https://www.google-analytics.com">
|
||||
|
||||
@@ -50,27 +77,34 @@
|
||||
|
||||
{% if site.google_analytics.pv.proxy_endpoint %}
|
||||
{% assign proxy_url = site.google_analytics.pv.proxy_endpoint
|
||||
| replace: "https://", "" | split: "/" | first | prepend: "https://" %}
|
||||
|
||||
| replace: "https://", "" | split: "/" | first | prepend: "https://" %}
|
||||
<link rel="preconnect" href="{{ proxy_url }}" crossorigin="use-credentials">
|
||||
<link rel="dns-prefetch" href="{{ proxy_url }}">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<!-- jsDelivr CDN -->
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net">
|
||||
<link rel="dns-prefetch" href="https://cdn.jsdelivr.net">
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="{{ site.data.assets[origin].bootstrap.css | relative_url}}">
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.11.2/css/all.min.css">
|
||||
<link rel="stylesheet" href="{{ site.data.assets[origin].fontawesome.css | relative_url }}">
|
||||
|
||||
{% include css-selector.html %}
|
||||
<link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}">
|
||||
|
||||
{% if site.toc and page.toc %}
|
||||
<link rel="stylesheet" href="{{ site.data.assets[origin].bootstrap-toc.css | relative_url }}">
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'page' or page.layout == 'post' %}
|
||||
<!-- Manific Popup -->
|
||||
<link rel="stylesheet" href="{{ site.data.assets[origin].magnific-popup.css | relative_url }}">
|
||||
{% endif %}
|
||||
|
||||
<!-- JavaScript -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
|
||||
<script src="{{ site.data.assets[origin].jquery.js | relative_url }}"></script>
|
||||
|
||||
{% unless site.theme_mode %}
|
||||
{% include mode-toggle.html %}
|
||||
{% endunless %}
|
||||
</head>
|
||||
|
||||
@@ -4,17 +4,42 @@
|
||||
|
||||
<!-- layout specified -->
|
||||
|
||||
{% if page.layout == 'home' or page.layout == 'post' %}
|
||||
{% if page.layout == 'post' %}
|
||||
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
|
||||
<!-- pv-report needs countup.js -->
|
||||
<script async src="https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js"></script>
|
||||
<script async src="{{ site.data.assets[origin].countup.js | relative_url }}"></script>
|
||||
<script defer src="{{ '/assets/js/dist/pvreport.min.js' | relative_url }}"></script>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'post' or page.layout == 'page' %}
|
||||
<!-- image lazy-loading & popup -->
|
||||
<script src="https://cdn.jsdelivr.net/combine/npm/lozad/dist/lozad.min.js,npm/magnific-popup@1/dist/jquery.magnific-popup.min.js"></script>
|
||||
<!-- image lazy-loading & popup & clipboard -->
|
||||
{% assign _urls = site.data.assets[origin].magnific-popup.js
|
||||
| append: ',' | append: site.data.assets[origin].lozad.js
|
||||
| append: ',' | append: site.data.assets[origin].clipboard.js
|
||||
%}
|
||||
|
||||
{% include jsdelivr-combine.html urls=_urls %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'home'
|
||||
or page.layout == 'post'
|
||||
or page.layout == 'archives'
|
||||
or page.layout == 'category'
|
||||
or page.layout == 'tag' %}
|
||||
|
||||
{% assign locale = site.lang | split: '-' | first %}
|
||||
|
||||
{% assign _urls = site.data.assets[origin].dayjs.js.common
|
||||
| append: ',' | append: site.data.assets[origin].dayjs.js.locale
|
||||
| replace: ':LOCALE', locale
|
||||
| append: ',' | append: site.data.assets[origin].dayjs.js.relativeTime
|
||||
| append: ',' | append: site.data.assets[origin].dayjs.js.localizedFormat
|
||||
%}
|
||||
|
||||
{% include jsdelivr-combine.html urls=_urls %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if page.layout == 'home'
|
||||
@@ -22,12 +47,16 @@
|
||||
or page.layout == 'post'
|
||||
or page.layout == 'page' %}
|
||||
{% assign type = page.layout %}
|
||||
{% elsif page.layout == 'archives'
|
||||
or page.layout == 'category'
|
||||
or page.layout == 'tag' %}
|
||||
{% assign type = "misc" %}
|
||||
{% else %}
|
||||
{% assign type = "commons" %}
|
||||
{% endif %}
|
||||
|
||||
{% assign js = type | prepend: '/assets/js/dist/' | append: '.min.js' %}
|
||||
<script defer src="{{ js | relative_url }}"></script>
|
||||
{% capture script %}/assets/js/dist/{{ type }}.min.js{% endcapture %}
|
||||
<script defer src="{{ script | relative_url }}"></script>
|
||||
|
||||
{% if page.math %}
|
||||
<!-- MathJax -->
|
||||
@@ -46,22 +75,25 @@
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
||||
<script type="text/javascript" id="MathJax-script" async
|
||||
src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
|
||||
<script src="{{ site.data.assets[origin].polyfill.js | relative_url }}"></script>
|
||||
<script id="MathJax-script" async src="{{ site.data.assets[origin].mathjax.js | relative_url }}">
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
<!-- commons -->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/combine/npm/popper.js@1.16.1,npm/bootstrap@4/dist/js/bootstrap.min.js"></script>
|
||||
<script src="{{ site.data.assets[origin].bootstrap.js | relative_url }}"></script>
|
||||
|
||||
{% if jekyll.environment == 'production' %}
|
||||
<!-- PWA -->
|
||||
<script defer src="{{ '/app.js' | relative_url }}"></script>
|
||||
{% if site.pwa.enabled %}
|
||||
<script defer src="{{ '/app.js' | relative_url }}"></script>
|
||||
{% else %}
|
||||
<script defer src="{{ '/unregister.js' | relative_url }}"></script>
|
||||
{% endif %}
|
||||
|
||||
<!-- GA -->
|
||||
{% if site.google_analytics.id %}
|
||||
{% if site.google_analytics.id != empty and site.google_analytics.id %}
|
||||
{% include google-analytics.html %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
32
_includes/jsdelivr-combine.html
Normal file
32
_includes/jsdelivr-combine.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{% assign urls = include.urls | split: ',' %}
|
||||
|
||||
{% assign combined_urls = nil %}
|
||||
|
||||
{% assign domain = 'https://cdn.jsdelivr.net/' %}
|
||||
|
||||
{% for url in urls %}
|
||||
|
||||
{% if url contains domain %}
|
||||
{% assign url_snippet = url | slice: domain.size, url.size %}
|
||||
|
||||
{% if combined_urls %}
|
||||
{% assign combined_urls = combined_urls | append: ',' | append: url_snippet %}
|
||||
{% else %}
|
||||
{% assign combined_urls = domain | append: 'combine/' | append: url_snippet %}
|
||||
{% endif %}
|
||||
|
||||
{% elsif url contains '//' %}
|
||||
|
||||
<script src="{{ url }}"></script>
|
||||
|
||||
{% else %}
|
||||
|
||||
<script src="{{ url | relative_url }}"></script>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% if combined_urls %}
|
||||
<script src="{{ combined_urls }}"></script>
|
||||
{% endif %}
|
||||
70
_includes/language-alias.html
Normal file
70
_includes/language-alias.html
Normal file
@@ -0,0 +1,70 @@
|
||||
{% comment %}
|
||||
|
||||
Convert the alias of the syntax language to the official name
|
||||
|
||||
See: <https://github.com/rouge-ruby/rouge/wiki/List-of-supported-languages-and-lexers>
|
||||
|
||||
{% endcomment %}
|
||||
|
||||
{% assign _lang = include.language | default: '' %}
|
||||
|
||||
{% case _lang %}
|
||||
{% when 'actionscript', 'as', 'as3' %}
|
||||
{{ 'ActionScript' }}
|
||||
{% when 'applescript' %}
|
||||
{{ 'AppleScript' }}
|
||||
{% when 'brightscript', 'bs', 'brs' %}
|
||||
{{ 'BrightScript' }}
|
||||
{% when 'cfscript', 'cfc' %}
|
||||
{{ 'CFScript' }}
|
||||
{% when 'coffeescript', 'coffee', 'coffee-script' %}
|
||||
{{ 'CoffeeScript' }}
|
||||
{% when 'cs', 'csharp' %}
|
||||
{{ 'C#' }}
|
||||
{% when 'erl' %}
|
||||
{{ 'Erlang' }}
|
||||
{% when 'graphql' %}
|
||||
{{ 'GraphQL' }}
|
||||
{% when 'haskell', 'hs' %}
|
||||
{{ 'Haskell' }}
|
||||
{% when 'javascript', 'js' %}
|
||||
{{ 'JavaScript' }}
|
||||
{% when 'make', 'mf', 'gnumake', 'bsdmake' %}
|
||||
{{ 'Makefile' }}
|
||||
{% when 'md', 'mkd' %}
|
||||
{{ 'Markdown' }}
|
||||
{% when 'm' %}
|
||||
{{ 'Matlab' }}
|
||||
{% when 'objective_c', 'objc', 'obj-c', 'obj_c', 'objectivec' %}
|
||||
{{ 'Objective-C' }}
|
||||
{% when 'perl', 'pl' %}
|
||||
{{ 'Perl' }}
|
||||
{% when 'php','php3','php4','php5' %}
|
||||
{{ 'PHP' }}
|
||||
{% when 'py' %}
|
||||
{{ 'Python' }}
|
||||
{% when 'rb' %}
|
||||
{{ 'Ruby' }}
|
||||
{% when 'rs','no_run','ignore','should_panic' %}
|
||||
{{ 'Rust' }}
|
||||
{% when 'bash', 'zsh', 'ksh', 'sh' %}
|
||||
{{ 'Shell' }}
|
||||
{% when 'st', 'squeak' %}
|
||||
{{ 'Smalltalk' }}
|
||||
{% when 'tex'%}
|
||||
{{ 'TeX' }}
|
||||
{% when 'latex' %}
|
||||
{{ 'LaTex' }}
|
||||
{% when 'ts', 'typescript' %}
|
||||
{{ 'TypeScript' }}
|
||||
{% when 'vb', 'visualbasic' %}
|
||||
{{ 'Visual Basic' }}
|
||||
{% when 'vue', 'vuejs' %}
|
||||
{{ 'Vue.js' }}
|
||||
{% when 'yml' %}
|
||||
{{ 'YAML' }}
|
||||
{% when 'css', 'html', 'scss', 'ssh', 'toml', 'xml', 'yaml', 'json' %}
|
||||
{{ _lang | upcase }}
|
||||
{% else %}
|
||||
{{ _lang | capitalize }}
|
||||
{% endcase %}
|
||||
@@ -2,14 +2,41 @@
|
||||
mermaid-js loader
|
||||
-->
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8/dist/mermaid.min.js"></script>
|
||||
<script src="{{ site.data.assets[origin].mermaid.js | relative_url }}"></script>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
(function () {
|
||||
|
||||
function updateMermaid(event) {
|
||||
if (event.source === window && event.data &&
|
||||
event.data.direction === ModeToggle.ID) {
|
||||
|
||||
const mode = event.data.message;
|
||||
|
||||
if (typeof mermaid === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
let expectedTheme = (mode === ModeToggle.DARK_MODE ? "dark" : "default");
|
||||
let config = {theme: expectedTheme};
|
||||
|
||||
/* Re-render the SVG › <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344> */
|
||||
$(".mermaid").each(function () {
|
||||
let svgCode = $(this).prev().children().html();
|
||||
$(this).removeAttr("data-processed");
|
||||
$(this).html(svgCode);
|
||||
});
|
||||
|
||||
mermaid.initialize(config);
|
||||
mermaid.init(undefined, ".mermaid");
|
||||
}
|
||||
}
|
||||
|
||||
let initTheme = "default";
|
||||
|
||||
if ($("html[mode=dark]").length > 0
|
||||
|| ($("html[mode]").length == 0
|
||||
&& window.matchMedia("(prefers-color-scheme: dark)").matches ) ) {
|
||||
if ($("html[data-mode=dark]").length > 0
|
||||
|| ($("html[data-mode]").length == 0
|
||||
&& window.matchMedia("(prefers-color-scheme: dark)").matches)) {
|
||||
initTheme = "dark";
|
||||
}
|
||||
|
||||
@@ -17,13 +44,16 @@
|
||||
theme: initTheme /* <default|dark|forest|neutral> */
|
||||
};
|
||||
|
||||
/* Markdown converts to HTML */
|
||||
$("pre").has("code.language-mermaid").each(function() {
|
||||
/* Create mermaid tag */
|
||||
$("pre").has("code.language-mermaid").each(function () {
|
||||
let svgCode = $(this).children().html();
|
||||
$(this).addClass("unloaded");
|
||||
$(this).after(`<div class=\"mermaid\">${svgCode}</div>`);
|
||||
$(this).after(`<pre class=\"mermaid\">${svgCode}</pre>`);
|
||||
});
|
||||
|
||||
mermaid.initialize(mermaidConf);
|
||||
});
|
||||
|
||||
window.addEventListener("message", updateMermaid);
|
||||
})();
|
||||
|
||||
</script>
|
||||
|
||||
@@ -2,14 +2,13 @@
|
||||
Switch the mode between dark and light.
|
||||
-->
|
||||
|
||||
<i class="mode-toggle fas fa-adjust"></i>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
class ModeToggle {
|
||||
static get MODE_KEY() { return "mode"; }
|
||||
static get MODE_ATTR() { return "data-mode"; }
|
||||
static get DARK_MODE() { return "dark"; }
|
||||
static get LIGHT_MODE() { return "light"; }
|
||||
static get ID() { return "mode-toggle"; }
|
||||
|
||||
constructor() {
|
||||
if (this.hasMode) {
|
||||
@@ -24,10 +23,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
var self = this;
|
||||
let self = this;
|
||||
|
||||
/* always follow the system prefers */
|
||||
this.sysDarkPrefers.addListener(function() {
|
||||
this.sysDarkPrefers.addEventListener("change", () => {
|
||||
if (self.hasMode) {
|
||||
if (self.isDarkMode) {
|
||||
if (!self.isSysDarkPrefer) {
|
||||
@@ -43,34 +42,19 @@
|
||||
self.clearMode();
|
||||
}
|
||||
|
||||
self.updateMermaid();
|
||||
self.notify();
|
||||
|
||||
});
|
||||
|
||||
} /* constructor() */
|
||||
|
||||
|
||||
setDark() {
|
||||
$('html').attr(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
|
||||
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
|
||||
}
|
||||
|
||||
setLight() {
|
||||
$('html').attr(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
|
||||
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
|
||||
}
|
||||
|
||||
clearMode() {
|
||||
$('html').removeAttr(ModeToggle.MODE_KEY);
|
||||
sessionStorage.removeItem(ModeToggle.MODE_KEY);
|
||||
}
|
||||
|
||||
get sysDarkPrefers() { return window.matchMedia("(prefers-color-scheme: dark)"); }
|
||||
|
||||
get isSysDarkPrefer() { return this.sysDarkPrefers.matches; }
|
||||
|
||||
get isDarkMode() { return this.mode == ModeToggle.DARK_MODE; }
|
||||
get isDarkMode() { return this.mode === ModeToggle.DARK_MODE; }
|
||||
|
||||
get isLightMode() { return this.mode == ModeToggle.LIGHT_MODE; }
|
||||
get isLightMode() { return this.mode === ModeToggle.LIGHT_MODE; }
|
||||
|
||||
get hasMode() { return this.mode != null; }
|
||||
|
||||
@@ -79,67 +63,67 @@
|
||||
/* get the current mode on screen */
|
||||
get modeStatus() {
|
||||
if (this.isDarkMode
|
||||
|| (!this.hasMode && this.isSysDarkPrefer) ) {
|
||||
|| (!this.hasMode && this.isSysDarkPrefer)) {
|
||||
return ModeToggle.DARK_MODE;
|
||||
} else {
|
||||
return ModeToggle.LIGHT_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
updateMermaid() {
|
||||
if (typeof mermaid !== "undefined") {
|
||||
let expectedTheme = (this.modeStatus === ModeToggle.DARK_MODE? "dark" : "default");
|
||||
let config = { theme: expectedTheme };
|
||||
|
||||
/* re-render the SVG › <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344> */
|
||||
$(".mermaid").each(function() {
|
||||
let svgCode = $(this).prev().children().html();
|
||||
$(this).removeAttr("data-processed");
|
||||
$(this).html(svgCode);
|
||||
});
|
||||
|
||||
mermaid.initialize(config);
|
||||
mermaid.init(undefined, ".mermaid");
|
||||
}
|
||||
setDark() {
|
||||
$('html').attr(ModeToggle.MODE_ATTR, ModeToggle.DARK_MODE);
|
||||
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
|
||||
}
|
||||
|
||||
flipMode() {
|
||||
if (this.hasMode) {
|
||||
if (this.isSysDarkPrefer) {
|
||||
if (this.isLightMode) {
|
||||
this.clearMode();
|
||||
} else {
|
||||
this.setLight();
|
||||
}
|
||||
setLight() {
|
||||
$('html').attr(ModeToggle.MODE_ATTR, ModeToggle.LIGHT_MODE);
|
||||
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (this.isDarkMode) {
|
||||
this.clearMode();
|
||||
} else {
|
||||
this.setDark();
|
||||
}
|
||||
}
|
||||
clearMode() {
|
||||
$('html').removeAttr(ModeToggle.MODE_ATTR);
|
||||
sessionStorage.removeItem(ModeToggle.MODE_KEY);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (this.isSysDarkPrefer) {
|
||||
this.setLight();
|
||||
} else {
|
||||
this.setDark();
|
||||
}
|
||||
}
|
||||
|
||||
this.updateMermaid();
|
||||
|
||||
} /* flipMode() */
|
||||
/* Notify another plugins that the theme mode has changed */
|
||||
notify() {
|
||||
window.postMessage({
|
||||
direction: ModeToggle.ID,
|
||||
message: this.modeStatus
|
||||
}, "*");
|
||||
}
|
||||
|
||||
} /* ModeToggle */
|
||||
|
||||
let toggle = new ModeToggle();
|
||||
const toggle = new ModeToggle();
|
||||
|
||||
$(".mode-toggle").click(function() {
|
||||
function flipMode() {
|
||||
if (toggle.hasMode) {
|
||||
if (toggle.isSysDarkPrefer) {
|
||||
if (toggle.isLightMode) {
|
||||
toggle.clearMode();
|
||||
} else {
|
||||
toggle.setLight();
|
||||
}
|
||||
|
||||
toggle.flipMode();
|
||||
} else {
|
||||
if (toggle.isDarkMode) {
|
||||
toggle.clearMode();
|
||||
} else {
|
||||
toggle.setDark();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
if (toggle.isSysDarkPrefer) {
|
||||
toggle.setLight();
|
||||
} else {
|
||||
toggle.setDark();
|
||||
}
|
||||
}
|
||||
|
||||
toggle.notify();
|
||||
|
||||
} /* flipMode() */
|
||||
|
||||
</script>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
{% comment %}
|
||||
Remove the zero padding from a month/day string
|
||||
{% endcomment %}
|
||||
|
||||
{% assign ret = include.date_str %}
|
||||
{% assign _first_chat = ret | slice: 0 %}
|
||||
|
||||
{% if _first_chat == '0' %}
|
||||
{% assign _last_idx = ret.size | minus: 1 %}
|
||||
{% assign ret = ret | slice: 1, _last_idx %}
|
||||
{% endif %}
|
||||
|
||||
{{ ret | replace: ' 0', ' ' }}
|
||||
@@ -1,57 +0,0 @@
|
||||
<!--
|
||||
The Pannel on right side (Desktop views)
|
||||
-->
|
||||
|
||||
<div id="panel-wrapper" class="col-xl-3 pl-2 text-muted topbar-down">
|
||||
|
||||
<div class="access">
|
||||
|
||||
{% include update-list.html %}
|
||||
|
||||
{% if update_list.size > 0 %}
|
||||
|
||||
<div id="access-lastmod" class="post">
|
||||
<span>{{- site.data.locales[site.lang].panel.lastmod | default: 'Recent Update' -}}</span>
|
||||
<ul class="post-content pl-0 pb-1 ml-1 mt-2">
|
||||
|
||||
{% for item in update_list %}
|
||||
{% assign index = item | split: "::" | last | plus: 0 %}
|
||||
{% assign post = site.posts[index] %}
|
||||
{% assign url = post.url | relative_url %}
|
||||
<li><a href="{{ url }}">{{ post.title }}</a></li>
|
||||
{% endfor %}
|
||||
|
||||
</ul>
|
||||
</div> <!-- #access-lastmod -->
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% include trending-tags.html %}
|
||||
|
||||
{% if trending_tags.size > 0 %}
|
||||
<div id="access-tags">
|
||||
<span>{{- site.data.locales[site.lang].panel.trending_tags | default: 'Trending Tags' -}}</span>
|
||||
<div class="d-flex flex-wrap mt-3 mb-1 mr-3">
|
||||
|
||||
{% for tag_name in trending_tags %}
|
||||
{% assign url = tag_name | slugify | url_encode | prepend: "/tags/" | append: "/" %}
|
||||
<a class="post-tag" href="{{ url | relative_url }}">{{ tag_name }}</a>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div> <!-- .access -->
|
||||
|
||||
{% if include.toc %}
|
||||
<!-- BS-toc.js will be loaded at medium priority -->
|
||||
<script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.js"></script>
|
||||
<div id="toc-wrapper" class="pl-0 pr-4 mb-5">
|
||||
<span class="pl-3 pt-2 mb-2">
|
||||
{{- site.data.locales[site.lang].panel.toc | default: 'Contents' -}}
|
||||
</span>
|
||||
<nav id="toc" data-toggle="toc"></nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div> <!-- #panel-wrapper -->
|
||||
@@ -5,26 +5,26 @@
|
||||
<div class="post-navigation d-flex justify-content-between">
|
||||
{% if page.previous.url %}
|
||||
<a href="{{ site.baseurl }}{{ page.previous.url }}" class="btn btn-outline-primary"
|
||||
prompt="{{ site.data.locales[site.lang].post.button.previous | default: 'previous' }}">
|
||||
prompt="{{ site.data.locales[site.lang].post.button.previous }}">
|
||||
<p>{{ page.previous.title }}</p>
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="btn btn-outline-primary disabled"
|
||||
prompt="{{ site.data.locales[site.lang].post.button.previous | default: 'previous' }}">
|
||||
<div class="btn btn-outline-primary disabled"
|
||||
prompt="{{ site.data.locales[site.lang].post.button.previous }}">
|
||||
<p>-</p>
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page.next.url %}
|
||||
<a href="{{ site.baseurl }}{{page.next.url}}" class="btn btn-outline-primary"
|
||||
prompt="{{ site.data.locales[site.lang].post.button.next | default: 'next' }}">
|
||||
prompt="{{ site.data.locales[site.lang].post.button.next }}">
|
||||
<p>{{ page.next.title }}</p>
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="btn btn-outline-primary disabled"
|
||||
prompt="{{ site.data.locales[site.lang].post.button.next | default: 'next' }}">
|
||||
<div class="btn btn-outline-primary disabled"
|
||||
prompt="{{ site.data.locales[site.lang].post.button.next }}">
|
||||
<p>-</p>
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
The paginator for post list on HomgPage.
|
||||
-->
|
||||
|
||||
<ul class="pagination align-items-center mt-4 mb-0 pl-lg-2">
|
||||
<ul class="pagination align-items-center mt-4 pl-lg-2">
|
||||
<!-- left arrow -->
|
||||
{% if paginator.previous_page %}
|
||||
{% assign prev_url = paginator.previous_page_path | relative_url %}
|
||||
@@ -47,7 +47,7 @@
|
||||
{% if show %}
|
||||
<!-- show number -->
|
||||
<li class="page-item {% if i == paginator.page %} active{% endif %}">
|
||||
<a class="page-link btn-box-shadow" href="{{ site.baseurl }}/{% if i > 1%}page{{ i }}/{% endif %}">{{ i }}</a>
|
||||
<a class="page-link btn-box-shadow" href="{% if i > 1 %}{{ site.paginate_path | replace: ':num', i | relative_url }}{% else %}{{ '/' | relative_url }}{% endif %}">{{ i }}</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<!-- hide number -->
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
-->
|
||||
|
||||
<div class="share-wrapper">
|
||||
<span class="share-label text-muted mr-1">{{ site.data.locales[site.lang].post.share | default: 'Share' }}</span>
|
||||
<span class="share-label text-muted mr-1">{{ site.data.locales[site.lang].post.share }}</span>
|
||||
<span class="share-icons">
|
||||
{% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
|
||||
{% assign url = page.url | absolute_url %}
|
||||
{% assign title = title | url_encode %}
|
||||
{% assign url = page.url | absolute_url | url_encode %}
|
||||
|
||||
{% for share in site.data.share.platforms %}
|
||||
{% assign link = share.link | replace: 'TITLE', title | replace: 'URL', url %}
|
||||
@@ -16,9 +17,10 @@
|
||||
</a>
|
||||
{% endfor %}
|
||||
|
||||
<i class="fa-fw fas fa-link small" onclick="copyLink('', '{{ site.data.locales[site.lang].post.button.copy.succeed }}')"
|
||||
<i id="copy-link" class="fa-fw fas fa-link small"
|
||||
data-toggle="tooltip" data-placement="top"
|
||||
title="{{ site.data.locales[site.lang].post.button.copy.title }}">
|
||||
title="{{ site.data.locales[site.lang].post.button.share_link.title }}"
|
||||
data-title-succeed="{{ site.data.locales[site.lang].post.button.share_link.succeed }}">
|
||||
</i>
|
||||
|
||||
</span>
|
||||
|
||||
@@ -16,14 +16,15 @@
|
||||
{% endunless %}
|
||||
|
||||
{% capture read_prompt %}
|
||||
{{- site.data.locales[site.lang].post.read_time.prompt | default: "read" -}}
|
||||
{{- site.data.locales[site.lang].post.read_time.prompt -}}
|
||||
{% endcapture %}
|
||||
|
||||
<!-- return element -->
|
||||
<span class="readtime" data-toggle="tooltip" data-placement="bottom"
|
||||
title="{{ words }} {{ site.data.locales[site.lang].post.words | default: "words" }}">
|
||||
{{- read_time -}}{{" "}}{{- site.data.locales[site.lang].post.read_time.unit | default: "min" -}}
|
||||
title="{{ words }} {{ site.data.locales[site.lang].post.words }}">
|
||||
<em>{{- read_time -}}{{" "}}{{- site.data.locales[site.lang].post.read_time.unit -}}</em>
|
||||
{%- if include.prompt -%}
|
||||
{% unless site.lang contains 'zh' %}{{" "}}{% endunless %}{{ read_prompt }}
|
||||
{%- assign _prompt_words = read_prompt | number_of_words: 'auto' -%}
|
||||
{%- unless _prompt_words > 1 -%}{{ " " }}{%- endunless -%}{{ read_prompt }}
|
||||
{%- endif -%}
|
||||
</span>
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
we suround the markdown table with `<div class="table-wrapper">` and `</div>`
|
||||
-->
|
||||
|
||||
{% if _content contains '<table>' %}
|
||||
{% if _content contains '<table' %}
|
||||
{% assign _content = _content
|
||||
| replace: '<table>', '<div class="table-wrapper"><table>'
|
||||
| replace: '<table', '<div class="table-wrapper"><table'
|
||||
| replace: '</table>', '</table></div>'
|
||||
| replace: '<code><div class="table-wrapper">', '<code>'
|
||||
| replace: '</table></div></code>', '</table></code>'
|
||||
%}
|
||||
{% endif %}
|
||||
@@ -30,71 +31,111 @@
|
||||
%}
|
||||
{% endif %}
|
||||
|
||||
<!-- Add attribute 'hide-bullet' to the checkbox list -->
|
||||
|
||||
{% if _content contains '<li class="task-list-item"><' %}
|
||||
<!-- Change the icon of checkbox -->
|
||||
{% if _content contains '<input type="checkbox"' %}
|
||||
{% assign _content = _content
|
||||
| replace: '"task-list-item"><', '"task-list-item" hide-bullet><'
|
||||
| replace:
|
||||
'<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />',
|
||||
'<i class="fas fa-check-circle fa-fw checked"></i>'
|
||||
| replace:
|
||||
'<input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />',
|
||||
'<i class="far fa-circle fa-fw"></i>'
|
||||
%}
|
||||
{% endif %}
|
||||
|
||||
|
||||
<!-- images -->
|
||||
|
||||
{% if _content contains '<img src="' %}
|
||||
|
||||
<!-- add CDN prefix if it exists -->
|
||||
|
||||
{% if site.img_cdn != '' %}
|
||||
{% assign img_path_replacement = '<img src="' | append: site.img_cdn | append: '/' %}
|
||||
{% else %}
|
||||
{% assign img_path_replacement = '<img src="' | append: site.baseurl | append: '/' %}
|
||||
{% endif %}
|
||||
|
||||
{% assign _content = _content | replace: '<img src="/', img_path_replacement %}
|
||||
|
||||
<!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
|
||||
|
||||
{% assign _content = _content | replace: '<img src="', '<img data-proofer-ignore data-src="' %}
|
||||
|
||||
<!-- add image placehoder to prevent layout reflow -->
|
||||
{% assign IMG_TAG = '<img ' %}
|
||||
|
||||
{% if _content contains IMG_TAG %}
|
||||
{% assign _img_content = nil %}
|
||||
{% assign _img_snippets = _content | split: IMG_TAG %}
|
||||
|
||||
{% assign _images = _content | split: '<img ' %}
|
||||
|
||||
{% for _img in _images %}
|
||||
{% for _img_snippet in _img_snippets %}
|
||||
{% if forloop.first %}
|
||||
{% assign _img_content = _img %}
|
||||
{% assign _img_content = _img_snippet %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% assign _width = nil %}
|
||||
{% assign _height = nil %}
|
||||
{% assign _attrs = _img | split: '>' | first | split: ' ' %}
|
||||
{% assign _src = nil %}
|
||||
|
||||
{% assign _left = _img_snippet | split: '>' | first %}
|
||||
{% assign _right = _img_snippet | remove: _left %}
|
||||
|
||||
{% assign _left = _left | remove: ' /' %}
|
||||
{% assign _left = _left | replace: ' w=', ' width=' | replace: ' h=', ' height=' %}
|
||||
{% assign _attrs = _left | split: ' ' %}
|
||||
|
||||
{% for _attr in _attrs %}
|
||||
{% capture _key %}{{ _attr | split: '=' | first }}{% endcapture %}
|
||||
{% capture _value %}{{ _attr | split: '=' | last | replace: '"', '' }}{% endcapture %}
|
||||
{% assign _pair = _attr | split: '=' %}
|
||||
{% if _pair.size < 2 %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% capture _key %}{{ _pair | first }}{% endcapture %}
|
||||
{% capture _value %}{{ _pair | last | replace: '"', '' }}{% endcapture %}
|
||||
|
||||
{% case _key %}
|
||||
{% when 'width' %}
|
||||
{% assign _width = _value %}
|
||||
{% when 'height' %}
|
||||
{% assign _height = _value %}
|
||||
{% when 'src' %}
|
||||
{% assign _src = _value %}
|
||||
{% endcase %}
|
||||
|
||||
{% if _width and _height %}
|
||||
{% capture _svg %}data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{_width}} {{_height}}'%3E%3C/svg%3E{% endcapture %}
|
||||
{% assign _img_content = _img_content | append: '<img src="' | append: _svg | append: '" ' | append: _img %}
|
||||
{% if _width and _height and _src %}
|
||||
{% break %}
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% unless _width and _height %}
|
||||
{% assign _img_content = _img_content | append: '<img ' | append: _img %}
|
||||
{% endunless %}
|
||||
{% if _src %}
|
||||
{% unless _src contains '://' %}
|
||||
|
||||
<!-- Add CDN URL -->
|
||||
{% if site.img_cdn %}
|
||||
{% if site.img_cdn contains '//' %}
|
||||
{% assign _src_prefix = site.img_cdn %}
|
||||
{% else %}
|
||||
{% assign _src_prefix = site.img_cdn | relative_url %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% assign _src_prefix = site.baseurl %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Add image path -->
|
||||
{% if page.img_path %}
|
||||
{% assign _path = page.img_path | append: '/' | replace: '//', '/' %}
|
||||
{% assign _src_prefix = _src_prefix | append: _path %}
|
||||
{% endif %}
|
||||
|
||||
{% assign _final_src = _src_prefix | append: _src %}
|
||||
{% assign _left = _left | replace: _src, _final_src %}
|
||||
|
||||
{% endunless %}
|
||||
|
||||
<!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
|
||||
|
||||
{% assign _left = _left | replace: 'src=', 'data-src=' %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<!-- Add SVG placehoder to prevent layout reflow -->
|
||||
|
||||
{% if _width and _height %}
|
||||
{%- capture _svg -%}
|
||||
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 {{ _width }} {{ _height }}'%3E%3C/svg%3E"
|
||||
{%- endcapture -%}
|
||||
|
||||
{% assign _left = _svg | append: ' ' | append: _left %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Bypass the HTML-proofer test -->
|
||||
{% assign _left = _left | append: ' data-proofer-ignore' %}
|
||||
|
||||
{% assign _img_content = _img_content | append: IMG_TAG | append: _left | append: _right %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
@@ -102,28 +143,137 @@
|
||||
|
||||
{% endif %}
|
||||
|
||||
<!-- Add lang-badge for code snippets -->
|
||||
<!-- Add header for code snippets -->
|
||||
|
||||
{% if _content contains '<div class="language-' %}
|
||||
{% assign _code_splits = _content | split: '<div class="language-' %}
|
||||
{% assign _new_content = nil %}
|
||||
{% if _content contains '<div class="highlight"><code>' %}
|
||||
{% assign _code_spippets = _content | split: '<div class="highlight"><code>' %}
|
||||
{% assign _new_content = '' %}
|
||||
|
||||
{% for _snippet in _code_spippets %}
|
||||
|
||||
{% if forloop.last %}
|
||||
{% assign _new_content = _new_content | append: _snippet %}
|
||||
|
||||
{% for _snippet in _code_splits %}
|
||||
{% if forloop.first %}
|
||||
{% assign _new_content = _snippet %}
|
||||
{% else %}
|
||||
{% assign _lang = _snippet | split: ' ' | first %}
|
||||
{% capture _tag_head %}<div lang="{{_lang}}" class="language-{% endcapture %}
|
||||
{% assign _new_content = _new_content | append: _tag_head | append: _snippet %}
|
||||
|
||||
{% assign _left = _snippet | split: '><' | last%}
|
||||
|
||||
{% if _left contains 'file="' %}
|
||||
{% assign _label_text = _left | split: 'file="' | last | split: '"' | first %}
|
||||
{% assign _label_icon = 'far fa-file-code' %}
|
||||
{% else %}
|
||||
{% assign _lang = _left | split: 'language-' | last | split: ' ' | first %}
|
||||
{% capture _label_text %}{% include language-alias.html language=_lang %}{% endcapture %}
|
||||
{% assign _label_icon = 'fas fa-code small' %}
|
||||
{% endif %}
|
||||
|
||||
{% capture _label %}
|
||||
<span data-label-text="{{ _label_text | strip }}"><i class="{{ _label_icon }}"></i></span>
|
||||
{% endcapture %}
|
||||
|
||||
{% assign _new_content = _new_content | append: _snippet
|
||||
| append: '<div class="code-header">'
|
||||
| append: _label
|
||||
| append: '<button aria-label="copy" data-title-succeed="'
|
||||
| append: site.data.locales[site.lang].post.button.copy_code.succeed
|
||||
| append: '"><i class="far fa-clipboard"></i></button></div>'
|
||||
| append: '<div class="highlight"><code>'
|
||||
%}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% if _new_content %}
|
||||
{% assign _content = _new_content %}
|
||||
{% endif %}
|
||||
{% assign _content = _new_content %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<!-- Create heading anchors -->
|
||||
|
||||
{% assign heading_levels = '2,3,4,5' | split: ',' %}
|
||||
{% assign _heading_content = _content %}
|
||||
|
||||
{% for level in heading_levels %}
|
||||
{% capture mark_start %}<h{{ level }} id="{% endcapture %}
|
||||
{% capture mark_end %}</h{{ level }}>{% endcapture %}
|
||||
|
||||
{% if _heading_content contains mark_start %}
|
||||
{% assign _new_content = nil %}
|
||||
{% assign heading_snippets = _heading_content | split: mark_start %}
|
||||
|
||||
{% for snippet in heading_snippets %}
|
||||
{% if forloop.first %}
|
||||
{% assign _new_content = snippet %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% assign id = snippet | split: '"' | first %}
|
||||
{% capture anchor %}<a href="#{{ id }}" class="anchor text-muted"><i class="fas fa-hashtag"></i></a>{% endcapture %}
|
||||
|
||||
{% assign left = snippet | split: mark_end | first %}
|
||||
{% assign right = snippet | slice: left.size, snippet.size %}
|
||||
{% assign left = left | replace_first: '">', '"><span class="mr-2">' | append: '</span>' %}
|
||||
|
||||
{% assign _new_content = _new_content | append: mark_start
|
||||
| append: left | append: anchor | append: right
|
||||
%}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% assign _heading_content = _new_content %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% assign _content = _heading_content %}
|
||||
|
||||
<!-- Wrap prompt element of blockquote with the <div> tag -->
|
||||
|
||||
{% assign blockquote_start = '<blockquote class=' %}
|
||||
{% assign blockquote_end = '</blockquote>' %}
|
||||
{% assign cls_prefix = 'prompt-' %}
|
||||
|
||||
{% if _content contains blockquote_start %}
|
||||
|
||||
{% assign _prompt_content = nil %}
|
||||
{% assign _prompt_snippets = _content | split: blockquote_start %}
|
||||
|
||||
{% for _snippet in _prompt_snippets %}
|
||||
|
||||
{% if forloop.first %}
|
||||
{% assign _prompt_content = _snippet %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
|
||||
{% assign left = _snippet | split: blockquote_end | first %}
|
||||
{% assign right = _snippet | slice: left.size, _snippet.size %}
|
||||
|
||||
{% assign cls_str = left | split: '>' | first %}
|
||||
{% assign cls_array = cls_str | remove: '"' | split: ' ' %}
|
||||
{% assign is_prompt = false %}
|
||||
|
||||
{% for cls in cls_array %}
|
||||
{% if cls contains cls_prefix %}
|
||||
{% assign is_prompt = true %}
|
||||
{% break %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% unless is_prompt %}
|
||||
{% assign _prompt_content = _prompt_content | append: blockquote_start | append: _snippet %}
|
||||
{% continue %}
|
||||
{% endunless %}
|
||||
|
||||
{% assign left = left | slice: cls_str.size, left.size %}
|
||||
{% assign left = cls_str | append: '><div' | append: left | append: '</div>' %}
|
||||
|
||||
{% assign _prompt_content = _prompt_content | append: blockquote_start | append: left | append: right %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% assign _content = _prompt_content %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
<!-- return -->
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
{% assign less = TOTAL_SIZE | minus: index_list.size %}
|
||||
|
||||
{% if less > 0 %}
|
||||
|
||||
{% for i in (0..last_index) %}
|
||||
{% assign post = site.posts[i] %}
|
||||
{% if post.url != page.url %}
|
||||
@@ -74,14 +73,12 @@
|
||||
{% endunless %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if index_list.size > 0 %}
|
||||
<div id="related-posts" class="mt-5 mb-2 mb-sm-4">
|
||||
<h3 class="pt-2 mt-1 mb-4 ml-1"
|
||||
data-toc-skip>{{ site.data.locales[site.lang].post.relate_posts | default: 'Further Reading' }}</h3>
|
||||
<div id="related-posts" class="mb-2 mb-sm-4">
|
||||
<h3 class="pt-2 mb-4 ml-1"
|
||||
data-toc-skip>{{ site.data.locales[site.lang].post.relate_posts }}</h3>
|
||||
<div class="card-deck mb-4">
|
||||
{% for entry in index_list %}
|
||||
{% assign index = entry | plus: 0 %}
|
||||
@@ -89,12 +86,12 @@
|
||||
<div class="card">
|
||||
<a href="{{ post.url | relative_url }}">
|
||||
<div class="card-body">
|
||||
{% include timeago.html date=post.date class="small" %}
|
||||
{% include datetime.html date=post.date class="small" %}
|
||||
<h3 class="pt-0 mt-1 mb-3" data-toc-skip>{{ post.title }}</h3>
|
||||
<div class="text-muted small">
|
||||
<p>
|
||||
{% include no-linenos.html content=post.content %}
|
||||
{{ content | markdownify | strip_html | truncate: 200 }}
|
||||
{{ content | markdownify | strip_html | truncate: 200 | escape }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
{% capture result_elem %}
|
||||
<div class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-lg-4 pr-lg-4 pl-xl-0 pr-xl-0">
|
||||
<a href="{{ site.url }}{url}">{title}</a>
|
||||
<a href="{url}">{title}</a>
|
||||
<div class="post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1">
|
||||
{categories}
|
||||
{tags}
|
||||
@@ -14,9 +14,9 @@
|
||||
</div>
|
||||
{% endcapture %}
|
||||
|
||||
{% capture not_found %}<p class="mt-5">Oops! No result founds.</p>{% endcapture %}
|
||||
{% capture not_found %}<p class="mt-5">{{ site.data.locales[site.lang].search.no_results }}</p>{% endcapture %}
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.7.3/dest/simple-jekyll-search.min.js"></script>
|
||||
<script src="{{ site.data.assets[origin].search.js | relative_url }}"></script>
|
||||
|
||||
<script>
|
||||
SimpleJekyllSearch({
|
||||
|
||||
@@ -4,15 +4,7 @@
|
||||
<div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
|
||||
<div class="col-12 col-sm-11 post-content">
|
||||
<div id="search-hints">
|
||||
<h4 class="text-muted mb-4">{{ site.data.locales[site.lang].panel.trending_tags | default: 'Trending Tags' }}</h4>
|
||||
|
||||
{% include trending-tags.html %}
|
||||
|
||||
{% for tag in trending_tags %}
|
||||
{% capture url %}/tags/{{ tag | slugify | url_encode }}/{% endcapture %}
|
||||
<a class="post-tag" href="{{ url | relative_url }}">{{ tag | replace: '-', ' ' }}</a>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
<div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div>
|
||||
</div>
|
||||
|
||||
@@ -2,24 +2,26 @@
|
||||
The Side Bar
|
||||
-->
|
||||
|
||||
<div id="sidebar" class="d-flex flex-column align-items-end" lang="{{lang}}">
|
||||
<div id="sidebar" class="d-flex flex-column align-items-end">
|
||||
<div class="profile-wrapper text-center">
|
||||
<div id="avatar">
|
||||
<a href="{{ '/' | relative_url }}" alt="avatar" class="mx-auto">
|
||||
{% capture avatar_url %}
|
||||
{%- if site.avatar contains '://' -%}
|
||||
{{ site.avatar }}
|
||||
{%- elsif site.img_cdn != '' and site.img_cdn -%}
|
||||
{{ site.avatar | prepend: site.img_cdn }}
|
||||
{%- else -%}
|
||||
{{ site.avatar | relative_url }}
|
||||
{%- endif -%}
|
||||
{% endcapture %}
|
||||
<img src="{{ avatar_url }}" alt="avatar" onerror="this.style.display='none'">
|
||||
<a href="{{ '/' | relative_url }}" class="mx-auto">
|
||||
{% if site.avatar != empty and site.avatar %}
|
||||
{% capture avatar_url %}
|
||||
{% if site.avatar contains '://' %}
|
||||
{{ site.avatar }}
|
||||
{% elsif site.img_cdn != empty and site.img_cdn %}
|
||||
{{ site.avatar | prepend: site.img_cdn }}
|
||||
{% else %}
|
||||
{{ site.avatar | relative_url }}
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
<img src="{{ avatar_url | strip }}" alt="avatar" onerror="this.style.display='none'">
|
||||
{% endif %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="site-title mt-3">
|
||||
<div class="site-title">
|
||||
<a href="{{ '/' | relative_url }}">{{ site.title }}</a>
|
||||
</div>
|
||||
<div class="site-subtitle font-italic">{{ site.tagline }}</div>
|
||||
@@ -32,7 +34,7 @@
|
||||
<li class="nav-item{% if page.layout == 'home' %}{{ " active" }}{% endif %}">
|
||||
<a href="{{ '/' | relative_url }}" class="nav-link">
|
||||
<i class="fa-fw fas fa-home ml-xl-3 mr-xl-3 unloaded"></i>
|
||||
<span>{{ site.data.locales[site.lang].tabs.home | default: "home" | upcase }}</span>
|
||||
<span>{{ site.data.locales[site.lang].tabs.home | upcase }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<!-- the real tabs -->
|
||||
@@ -42,14 +44,24 @@
|
||||
<i class="fa-fw {{ tab.icon }} ml-xl-3 mr-xl-3 unloaded"></i>
|
||||
{% capture tab_name %}{{ tab.url | split: '/' }}{% endcapture %}
|
||||
|
||||
<span>{{ site.data.locales[site.lang].tabs.[tab_name] | default: tab_name | upcase }}</span>
|
||||
<span>{{ site.data.locales[site.lang].tabs.[tab_name] | default: tab.title | upcase }}</span>
|
||||
</a>
|
||||
</li> <!-- .nav-item -->
|
||||
{% endfor %}
|
||||
|
||||
</ul> <!-- ul.nav.flex-column -->
|
||||
|
||||
<div class="sidebar-bottom mt-auto d-flex flex-wrap justify-content-center">
|
||||
<div class="sidebar-bottom mt-auto d-flex flex-wrap justify-content-center align-items-center">
|
||||
|
||||
{% unless site.theme_mode %}
|
||||
<button class="mode-toggle btn" aria-label="Switch Mode">
|
||||
<i class="fas fa-adjust"></i>
|
||||
</button>
|
||||
|
||||
{% if site.data.contact.size > 0 %}
|
||||
<span class="icon-border"></span>
|
||||
{% endif %}
|
||||
{% endunless %}
|
||||
|
||||
{% for entry in site.data.contact %}
|
||||
{% capture url %}
|
||||
@@ -69,7 +81,6 @@
|
||||
|
||||
{% if url %}
|
||||
<a href="{{ url }}" aria-label="{{ entry.type }}"
|
||||
{% unless site.theme_mode %}class="order-{{ forloop.index | plus: 2 }}"{% endunless %}
|
||||
{% unless entry.noblank %}target="_blank" rel="noopener"{% endunless %}>
|
||||
<i class="{{ entry.icon }}"></i>
|
||||
</a>
|
||||
@@ -77,16 +88,6 @@
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% unless site.theme_mode %}
|
||||
{% if site.data.contact.size > 0 %}
|
||||
<span class="icon-border order-2"></span>
|
||||
{% endif %}
|
||||
|
||||
<span id="mode-toggle-wrapper" class="order-1">
|
||||
{% include mode-toggle.html %}
|
||||
</span>
|
||||
{% endunless %}
|
||||
|
||||
</div> <!-- .sidebar-bottom -->
|
||||
|
||||
</div><!-- #sidebar -->
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
<!--
|
||||
Date format snippet
|
||||
See: /assets/js/_utils/timeage.js
|
||||
-->
|
||||
|
||||
{% assign tooltip_df = site.data.locales[site.lang].date_format.tooltip | default: '%a, %b %e, %Y, %l:%M %p %z' %}
|
||||
{% assign post_long_df = site.data.locales[site.lang].date_format.post.long | default: '%b %e, %Y' %}
|
||||
{% assign post_short_df = site.data.locales[site.lang].date_format.post.short | default: '%b %e' %}
|
||||
|
||||
{% if include.preposition %}
|
||||
{{ include.preposition }}
|
||||
{% endif %}
|
||||
<span class="timeago {% if include.class %}{{ include.class }}{% endif %}"
|
||||
{% if include.tooltip %}
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="{{ include.date | date: tooltip_df }}"
|
||||
{% endif %}>
|
||||
{%- assign this_year = site.time | date: "%Y" -%}
|
||||
{%- assign post_year = include.date | date: "%Y" -%}
|
||||
{%- if post_year == this_year -%}
|
||||
{{ include.date | date: post_short_df }}
|
||||
{%- else -%}
|
||||
{{ include.date | date: post_long_df }}
|
||||
{%- endif -%}
|
||||
<i class="unloaded">{{ include.date | date_to_xmlschema }}</i>
|
||||
</span>
|
||||
16
_includes/toc.html
Normal file
16
_includes/toc.html
Normal file
@@ -0,0 +1,16 @@
|
||||
{% assign enable_toc = false %}
|
||||
{% if site.toc and page.toc %}
|
||||
{% if page.content contains '<h2' or page.content contains '<h3' %}
|
||||
{% assign enable_toc = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if enable_toc %}
|
||||
<!-- BS-toc.js will be loaded at medium priority -->
|
||||
<script src="{{ site.data.assets[origin].bootstrap-toc.js | relative_url }}"></script>
|
||||
|
||||
<div id="toc-wrapper" class="pl-0 pr-4 mb-5">
|
||||
<div class="panel-heading pl-3 pt-2 mb-2">{{- site.data.locales[site.lang].panel.toc -}}</div>
|
||||
<nav id="toc" data-toggle="toc"></nav>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -2,15 +2,15 @@
|
||||
The Top Bar
|
||||
-->
|
||||
|
||||
<div id="topbar-wrapper" class="row justify-content-center topbar-down">
|
||||
<div id="topbar" class="col-11 d-flex h-100 align-items-center justify-content-between">
|
||||
<div id="topbar-wrapper">
|
||||
<div id="topbar" class="container d-flex align-items-center justify-content-between h-100 pl-3 pr-3 pl-md-4 pr-md-4">
|
||||
<span id="breadcrumb">
|
||||
|
||||
{% assign paths = page.url | split: '/' %}
|
||||
|
||||
{% if paths.size == 0 or page.layout == 'home' %}
|
||||
<!-- index page -->
|
||||
<span>{{ site.data.locales[site.lang].tabs.home | default: 'home' | capitalize }}</span>
|
||||
<span>{{ site.data.locales[site.lang].tabs.home | capitalize }}</span>
|
||||
|
||||
{% else %}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
{% if forloop.first %}
|
||||
<span>
|
||||
<a href="{{ '/' | relative_url }}">
|
||||
{{ site.data.locales[site.lang].tabs.home | default: 'home' | capitalize }}
|
||||
{{ site.data.locales[site.lang].tabs.home | capitalize }}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
@@ -31,16 +31,12 @@
|
||||
<span>{{ page.title }}</span>
|
||||
{% endif %}
|
||||
|
||||
{% else %}
|
||||
|
||||
{% unless page.layout == 'post' %}
|
||||
<span>
|
||||
<a href="{{ item | relative_url }}">
|
||||
{{ site.data.locales[site.lang].tabs[item] | default: page.title }}
|
||||
</a>
|
||||
</span>
|
||||
{% endunless %}
|
||||
|
||||
{% elsif page.layout == 'category' or page.layout == 'tag' %}
|
||||
<span>
|
||||
<a href="{{ item | relative_url }}">
|
||||
{{ site.data.locales[site.lang].tabs[item] | default: page.title }}
|
||||
</a>
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
@@ -54,7 +50,7 @@
|
||||
<div id="topbar-title">
|
||||
{% if page.layout == 'home' %}
|
||||
{{- site.data.locales[site.lang].title | default: site.title -}}
|
||||
{% elsif page.collection == 'tabs' %}
|
||||
{% elsif page.collection == 'tabs' or page.layout == 'page' %}
|
||||
{%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%}
|
||||
{{- site.data.locales[site.lang].tabs[tab_key] | default: page.title -}}
|
||||
{% else %}
|
||||
@@ -66,10 +62,9 @@
|
||||
<span id="search-wrapper" class="align-items-center">
|
||||
<i class="fas fa-search fa-fw"></i>
|
||||
<input class="form-control" id="search-input" type="search"
|
||||
aria-label="search" autocomplete="off" placeholder="{{ site.data.locales[site.lang].search.hint | default: 'Search' | capitalize }}...">
|
||||
<i class="fa fa-times-circle fa-fw" id="search-cleaner"></i>
|
||||
aria-label="search" autocomplete="off" placeholder="{{ site.data.locales[site.lang].search.hint | capitalize }}...">
|
||||
</span>
|
||||
<span id="search-cancel" >{{ site.data.locales[site.lang].search.cancel | default: 'Cancel' }}</span>
|
||||
<span id="search-cancel" >{{ site.data.locales[site.lang].search.cancel }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -34,3 +34,17 @@
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% if trending_tags.size > 0 %}
|
||||
<div id="access-tags">
|
||||
<div class="panel-heading">{{- site.data.locales[site.lang].panel.trending_tags -}}</div>
|
||||
<div class="d-flex flex-wrap mt-3 mb-1 mr-3">
|
||||
|
||||
{% for tag_name in trending_tags %}
|
||||
{% assign url = tag_name | slugify | url_encode | prepend: "/tags/" | append: "/" %}
|
||||
<a class="post-tag" href="{{ url | relative_url }}">{{ tag_name }}</a>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -22,3 +22,19 @@
|
||||
{% for entry in all_list limit:MAX_SIZE %}
|
||||
{% assign update_list = update_list | push: entry %}
|
||||
{% endfor %}
|
||||
|
||||
{% if update_list.size > 0 %}
|
||||
|
||||
<div id="access-lastmod" class="post">
|
||||
<div class="panel-heading">{{- site.data.locales[site.lang].panel.lastmod -}}</div>
|
||||
<ul class="post-content pl-0 pb-1 ml-1 mt-2">
|
||||
{% for item in update_list %}
|
||||
{% assign index = item | split: "::" | last | plus: 0 %}
|
||||
{% assign post = site.posts[index] %}
|
||||
{% assign url = post.url | relative_url %}
|
||||
<li><a href="{{ url }}">{{ post.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div> <!-- #access-lastmod -->
|
||||
|
||||
{% endif %}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
Reference: https://bootsnipp.com/snippets/featured/link-to-top-page
|
||||
*/
|
||||
/**
|
||||
* Reference: https://bootsnipp.com/snippets/featured/link-to-top-page
|
||||
*/
|
||||
$(function() {
|
||||
$(window).scroll(() => {
|
||||
if ($(this).scrollTop() > 50 &&
|
||||
$("#sidebar-trigger").css("display") === "none") {
|
||||
$("#back-to-top").fadeIn();
|
||||
} else {
|
||||
$("#back-to-top").fadeOut();
|
||||
}
|
||||
});
|
||||
$(window).scroll(() => {
|
||||
if ($(this).scrollTop() > 50 &&
|
||||
$("#sidebar-trigger").css("display") === "none") {
|
||||
$("#back-to-top").fadeIn();
|
||||
} else {
|
||||
$("#back-to-top").fadeOut();
|
||||
}
|
||||
});
|
||||
|
||||
$("#back-to-top").click(() => {
|
||||
$("body,html").animate({
|
||||
scrollTop: 0
|
||||
}, 800);
|
||||
return false;
|
||||
});
|
||||
$("#back-to-top").click(() => {
|
||||
$("body,html").animate({
|
||||
scrollTop: 0
|
||||
}, 800);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
13
_javascript/commons/mode-toggle.js
Normal file
13
_javascript/commons/mode-toggle.js
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Listener for theme mode toggle
|
||||
*/
|
||||
$(function () {
|
||||
$(".mode-toggle").click((e) => {
|
||||
const $target = $(e.target);
|
||||
let $btn = ($target.prop("tagName") === "button".toUpperCase() ?
|
||||
$target : $target.parent());
|
||||
|
||||
$btn.blur(); // remove the clicking outline
|
||||
flipMode();
|
||||
});
|
||||
});
|
||||
38
_javascript/commons/scroll-helper.js
Normal file
38
_javascript/commons/scroll-helper.js
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* A tool for smooth scrolling and topbar switcher
|
||||
*/
|
||||
const ScrollHelper = (function () {
|
||||
const $body = $("body");
|
||||
const ATTR_TOPBAR_VISIBLE = "data-topbar-visible";
|
||||
const topbarHeight = $("#topbar-wrapper").outerHeight();
|
||||
|
||||
let scrollUpCount = 0; // the number of times the scroll up was triggered by ToC or anchor
|
||||
let topbarLocked = false;
|
||||
let orientationLocked = false;
|
||||
|
||||
return {
|
||||
hideTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, false),
|
||||
showTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, true),
|
||||
|
||||
// scroll up
|
||||
|
||||
addScrollUpTask: () => {
|
||||
scrollUpCount += 1;
|
||||
if (!topbarLocked) {
|
||||
topbarLocked = true;
|
||||
}
|
||||
},
|
||||
popScrollUpTask: () => scrollUpCount -= 1,
|
||||
hasScrollUpTask: () => scrollUpCount > 0,
|
||||
topbarLocked: () => topbarLocked === true,
|
||||
unlockTopbar: () => topbarLocked = false,
|
||||
getTopbarHeight: () => topbarHeight,
|
||||
|
||||
// orientation change
|
||||
|
||||
orientationLocked: () => orientationLocked === true,
|
||||
lockOrientation: () => orientationLocked = true,
|
||||
unLockOrientation: () => orientationLocked = false
|
||||
};
|
||||
|
||||
}());
|
||||
@@ -1,153 +1,129 @@
|
||||
/*
|
||||
* This script make #search-result-wrapper switch to unloaded or shown automatically.
|
||||
*/
|
||||
/**
|
||||
* This script make #search-result-wrapper switch to unloaded or shown automatically.
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
$(function () {
|
||||
const btnSbTrigger = $("#sidebar-trigger");
|
||||
const btnSearchTrigger = $("#search-trigger");
|
||||
const btnCancel = $("#search-cancel");
|
||||
const main = $("#main");
|
||||
const topbarTitle = $("#topbar-title");
|
||||
const searchWrapper = $("#search-wrapper");
|
||||
const resultWrapper = $("#search-result-wrapper");
|
||||
const results = $("#search-results");
|
||||
const input = $("#search-input");
|
||||
const hints = $("#search-hints");
|
||||
|
||||
const btnSbTrigger = $("#sidebar-trigger");
|
||||
const btnSearchTrigger = $("#search-trigger");
|
||||
const btnCancel = $("#search-cancel");
|
||||
const btnClear = $("#search-cleaner");
|
||||
const scrollBlocker = (function () {
|
||||
let offset = 0;
|
||||
return {
|
||||
block() {
|
||||
offset = window.scrollY;
|
||||
$("html,body").scrollTop(0);
|
||||
},
|
||||
release() {
|
||||
$("html,body").scrollTop(offset);
|
||||
},
|
||||
getOffset() {
|
||||
return offset;
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
const main = $("#main");
|
||||
const topbarTitle = $("#topbar-title");
|
||||
const searchWrapper = $("#search-wrapper");
|
||||
const resultWrapper = $("#search-result-wrapper");
|
||||
const results = $("#search-results");
|
||||
const input = $("#search-input");
|
||||
const hints = $("#search-hints");
|
||||
/*--- Actions in mobile screens (Sidebar hidden) ---*/
|
||||
|
||||
const scrollBlocker = (function () {
|
||||
let offset = 0;
|
||||
return {
|
||||
block() {
|
||||
offset = window.scrollY;
|
||||
$("html,body").scrollTop(0);
|
||||
},
|
||||
release() {
|
||||
$("html,body").scrollTop(offset);
|
||||
},
|
||||
getOffset() {
|
||||
return offset;
|
||||
}
|
||||
};
|
||||
}());
|
||||
const mobileSearchBar = (function () {
|
||||
return {
|
||||
on() {
|
||||
btnSbTrigger.addClass("unloaded");
|
||||
topbarTitle.addClass("unloaded");
|
||||
btnSearchTrigger.addClass("unloaded");
|
||||
searchWrapper.addClass("d-flex");
|
||||
btnCancel.addClass("loaded");
|
||||
},
|
||||
off() {
|
||||
btnCancel.removeClass("loaded");
|
||||
searchWrapper.removeClass("d-flex");
|
||||
btnSbTrigger.removeClass("unloaded");
|
||||
topbarTitle.removeClass("unloaded");
|
||||
btnSearchTrigger.removeClass("unloaded");
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
const resultSwitch = (function () {
|
||||
let visible = false;
|
||||
|
||||
/*--- Actions in small screens (Sidebar unloaded) ---*/
|
||||
return {
|
||||
on() {
|
||||
if (!visible) {
|
||||
// the block method must be called before $(#main) unloaded.
|
||||
scrollBlocker.block();
|
||||
resultWrapper.removeClass("unloaded");
|
||||
main.addClass("unloaded");
|
||||
visible = true;
|
||||
}
|
||||
},
|
||||
off() {
|
||||
if (visible) {
|
||||
results.empty();
|
||||
if (hints.hasClass("unloaded")) {
|
||||
hints.removeClass("unloaded");
|
||||
}
|
||||
resultWrapper.addClass("unloaded");
|
||||
main.removeClass("unloaded");
|
||||
|
||||
const mobileSearchBar = (function () {
|
||||
return {
|
||||
on() {
|
||||
btnSbTrigger.addClass("unloaded");
|
||||
topbarTitle.addClass("unloaded");
|
||||
btnSearchTrigger.addClass("unloaded");
|
||||
searchWrapper.addClass("d-flex");
|
||||
btnCancel.addClass("loaded");
|
||||
},
|
||||
off() {
|
||||
btnCancel.removeClass("loaded");
|
||||
searchWrapper.removeClass("d-flex");
|
||||
btnSbTrigger.removeClass("unloaded");
|
||||
topbarTitle.removeClass("unloaded");
|
||||
btnSearchTrigger.removeClass("unloaded");
|
||||
}
|
||||
};
|
||||
}());
|
||||
// now the release method must be called after $(#main) display
|
||||
scrollBlocker.release();
|
||||
|
||||
const resultSwitch = (function () {
|
||||
let visible = false;
|
||||
input.val("");
|
||||
visible = false;
|
||||
}
|
||||
},
|
||||
isVisible() {
|
||||
return visible;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
on() {
|
||||
if (!visible) {
|
||||
// the block method must be called before $(#main) unloaded.
|
||||
scrollBlocker.block();
|
||||
resultWrapper.removeClass("unloaded");
|
||||
main.addClass("unloaded");
|
||||
visible = true;
|
||||
}
|
||||
},
|
||||
off() {
|
||||
if (visible) {
|
||||
results.empty();
|
||||
if (hints.hasClass("unloaded")) {
|
||||
hints.removeClass("unloaded");
|
||||
}
|
||||
resultWrapper.addClass("unloaded");
|
||||
btnClear.removeClass("visible");
|
||||
main.removeClass("unloaded");
|
||||
}());
|
||||
|
||||
// now the release method must be called after $(#main) display
|
||||
scrollBlocker.release();
|
||||
function isMobileView() {
|
||||
return btnCancel.hasClass("loaded");
|
||||
}
|
||||
|
||||
input.val("");
|
||||
visible = false;
|
||||
}
|
||||
},
|
||||
isVisible() {
|
||||
return visible;
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
|
||||
function isMobileView() {
|
||||
return btnCancel.hasClass("loaded");
|
||||
}
|
||||
|
||||
btnSearchTrigger.click(function() {
|
||||
mobileSearchBar.on();
|
||||
resultSwitch.on();
|
||||
input.focus();
|
||||
});
|
||||
|
||||
btnCancel.click(function() {
|
||||
mobileSearchBar.off();
|
||||
resultSwitch.off();
|
||||
});
|
||||
|
||||
input.focus(function() {
|
||||
searchWrapper.addClass("input-focus");
|
||||
});
|
||||
|
||||
input.focusout(function() {
|
||||
searchWrapper.removeClass("input-focus");
|
||||
});
|
||||
|
||||
input.on("keyup", function(e) {
|
||||
if (e.keyCode === 8 && input.val() === "") {
|
||||
if (!isMobileView()) {
|
||||
resultSwitch.off();
|
||||
} else {
|
||||
hints.removeClass("unloaded");
|
||||
}
|
||||
} else {
|
||||
if (input.val() !== "") {
|
||||
btnSearchTrigger.click(function () {
|
||||
mobileSearchBar.on();
|
||||
resultSwitch.on();
|
||||
input.focus();
|
||||
});
|
||||
|
||||
if (!btnClear.hasClass("visible")) {
|
||||
btnClear.addClass("visible");
|
||||
btnCancel.click(function () {
|
||||
mobileSearchBar.off();
|
||||
resultSwitch.off();
|
||||
});
|
||||
|
||||
input.focus(function () {
|
||||
searchWrapper.addClass("input-focus");
|
||||
});
|
||||
|
||||
input.focusout(function () {
|
||||
searchWrapper.removeClass("input-focus");
|
||||
});
|
||||
|
||||
input.on("input", () => {
|
||||
if (input.val() === "") {
|
||||
if (isMobileView()) {
|
||||
hints.removeClass("unloaded");
|
||||
} else {
|
||||
resultSwitch.off();
|
||||
}
|
||||
|
||||
} else {
|
||||
resultSwitch.on();
|
||||
if (isMobileView()) {
|
||||
hints.addClass("unloaded");
|
||||
}
|
||||
}
|
||||
|
||||
if (isMobileView()) {
|
||||
hints.addClass("unloaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
btnClear.on("click", function() {
|
||||
input.val("");
|
||||
if (isMobileView()) {
|
||||
hints.removeClass("unloaded");
|
||||
results.empty();
|
||||
} else {
|
||||
resultSwitch.off();
|
||||
}
|
||||
input.focus();
|
||||
btnClear.removeClass("visible");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -2,29 +2,27 @@
|
||||
* Expand or close the sidebar in mobile screens.
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
$(function () {
|
||||
const sidebarUtil = (function () {
|
||||
const ATTR_DISPLAY = "sidebar-display";
|
||||
let isExpanded = false;
|
||||
const body = $("body");
|
||||
|
||||
const sidebarUtil = (function () {
|
||||
const ATTR_DISPLAY = "sidebar-display";
|
||||
let isExpanded = false;
|
||||
const body = $("body");
|
||||
return {
|
||||
toggle() {
|
||||
if (isExpanded === false) {
|
||||
body.attr(ATTR_DISPLAY, "");
|
||||
} else {
|
||||
body.removeAttr(ATTR_DISPLAY);
|
||||
}
|
||||
|
||||
return {
|
||||
toggle() {
|
||||
if (isExpanded === false) {
|
||||
body.attr(ATTR_DISPLAY, "");
|
||||
} else {
|
||||
body.removeAttr(ATTR_DISPLAY);
|
||||
}
|
||||
isExpanded = !isExpanded;
|
||||
}
|
||||
};
|
||||
|
||||
isExpanded = !isExpanded;
|
||||
}
|
||||
};
|
||||
}());
|
||||
|
||||
}());
|
||||
|
||||
$("#sidebar-trigger").click(sidebarUtil.toggle);
|
||||
|
||||
$("#mask").click(sidebarUtil.toggle);
|
||||
$("#sidebar-trigger").click(sidebarUtil.toggle);
|
||||
|
||||
$("#mask").click(sidebarUtil.toggle);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Initial Bootstrap Tooltip.
|
||||
*/
|
||||
*/
|
||||
$(function () {
|
||||
$("[data-toggle=\"tooltip\"]").tooltip();
|
||||
$("[data-toggle=\"tooltip\"]").tooltip();
|
||||
});
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Hide Header on scroll down
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
|
||||
const topbarWrapper = $("#topbar-wrapper");
|
||||
const toc = $("#toc-wrapper");
|
||||
const access = $(".access");
|
||||
const searchInput = $("#search-input");
|
||||
|
||||
let didScroll;
|
||||
let lastScrollTop = 0;
|
||||
|
||||
const delta = 5;
|
||||
const topbarHeight = topbarWrapper.outerHeight();
|
||||
|
||||
function hasScrolled() {
|
||||
var st = $(this).scrollTop();
|
||||
|
||||
/* Make sure they scroll more than delta */
|
||||
if (Math.abs(lastScrollTop - st) <= delta) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (st > lastScrollTop && st > topbarHeight) {
|
||||
/* Scroll Down */
|
||||
topbarWrapper.removeClass("topbar-down").addClass("topbar-up");
|
||||
|
||||
if (toc.length > 0) {
|
||||
toc.removeClass("topbar-down");
|
||||
}
|
||||
|
||||
if (access.length > 0) {
|
||||
access.removeClass("topbar-down");
|
||||
}
|
||||
|
||||
if (searchInput.is(":focus")) {
|
||||
searchInput.blur(); /* remove focus */
|
||||
}
|
||||
|
||||
} else if (st + $(window).height() < $(document).height()) {
|
||||
/* Scroll Up */
|
||||
topbarWrapper.removeClass("topbar-up").addClass("topbar-down");
|
||||
if (toc.length > 0) {
|
||||
toc.addClass("topbar-down");
|
||||
}
|
||||
if (access.length > 0) {
|
||||
access.addClass("topbar-down");
|
||||
}
|
||||
}
|
||||
|
||||
lastScrollTop = st;
|
||||
}
|
||||
|
||||
$(window).scroll(function(event) {
|
||||
if ($("#topbar-title").is(":hidden")) { /* Not in small screens */
|
||||
didScroll = true;
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(function() {
|
||||
if (didScroll) {
|
||||
hasScrolled();
|
||||
didScroll = false;
|
||||
}
|
||||
}, 250);
|
||||
|
||||
});
|
||||
89
_javascript/commons/topbar-switcher.js
Normal file
89
_javascript/commons/topbar-switcher.js
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Hide Header on scroll down
|
||||
*/
|
||||
|
||||
$(function () {
|
||||
const $searchInput = $("#search-input");
|
||||
const delta = ScrollHelper.getTopbarHeight();
|
||||
|
||||
let didScroll;
|
||||
let lastScrollTop = 0;
|
||||
|
||||
function hasScrolled() {
|
||||
let st = $(this).scrollTop();
|
||||
|
||||
/* Make sure they scroll more than delta */
|
||||
if (Math.abs(lastScrollTop - st) <= delta) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (st > lastScrollTop) { // Scroll Down
|
||||
ScrollHelper.hideTopbar();
|
||||
|
||||
if ($searchInput.is(":focus")) {
|
||||
$searchInput.blur(); /* remove focus */
|
||||
}
|
||||
|
||||
} else { // Scroll up
|
||||
// has not yet scrolled to the bottom of the screen, that is, there is still space for scrolling
|
||||
if (st + $(window).height() < $(document).height()) {
|
||||
|
||||
if (ScrollHelper.hasScrollUpTask()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ScrollHelper.topbarLocked()) { // avoid redundant scroll up event from smooth scrolling
|
||||
ScrollHelper.unlockTopbar();
|
||||
} else {
|
||||
if (ScrollHelper.orientationLocked()) { // avoid device auto scroll up on orientation change
|
||||
ScrollHelper.unLockOrientation();
|
||||
} else {
|
||||
ScrollHelper.showTopbar();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lastScrollTop = st;
|
||||
|
||||
} // hasScrolled()
|
||||
|
||||
function handleLandscape() {
|
||||
if ($(window).scrollTop() === 0) {
|
||||
return;
|
||||
}
|
||||
ScrollHelper.lockOrientation();
|
||||
ScrollHelper.hideTopbar();
|
||||
}
|
||||
|
||||
if (screen.orientation) {
|
||||
screen.orientation.onchange = () => {
|
||||
const type = screen.orientation.type;
|
||||
if (type === "landscape-primary" || type === "landscape-secondary") {
|
||||
handleLandscape();
|
||||
}
|
||||
};
|
||||
|
||||
} else {
|
||||
// for the browsers that not support `window.screen.orientation` API
|
||||
$(window).on("orientationchange", () => {
|
||||
if ($(window).width() < $(window).height()) { // before rotating, it is still in portrait mode.
|
||||
handleLandscape();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(window).scroll(() => {
|
||||
if (didScroll) {
|
||||
return;
|
||||
}
|
||||
didScroll = true;
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
if (didScroll) {
|
||||
hasScrolled();
|
||||
didScroll = false;
|
||||
}
|
||||
}, 250);
|
||||
});
|
||||
@@ -1,47 +1,67 @@
|
||||
/*
|
||||
* Top bar title auto change while scrolling in mobile screens.
|
||||
*/
|
||||
/**
|
||||
* Top bar title auto change while scrolling up/down in mobile screens.
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
$(function () {
|
||||
const titleSelector = "div.post>h1:first-of-type";
|
||||
const $pageTitle = $(titleSelector);
|
||||
const $topbarTitle = $("#topbar-title");
|
||||
|
||||
const topbarTitle = $("#topbar-title");
|
||||
const postTitle = $("div.post>h1");
|
||||
|
||||
const DEFAULT = topbarTitle.text().trim();
|
||||
|
||||
let title = (postTitle.length > 0) ?
|
||||
postTitle.text().trim() : $("h1").text().trim();
|
||||
|
||||
if ($("#page-category").length || $("#page-tag").length) {
|
||||
/* The title in Category or Tag page will be "<title> <count_of_posts>" */
|
||||
if (/\s/.test(title)) {
|
||||
title = title.replace(/[0-9]/g, "").trim();
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace topbar title while scroll screens. */
|
||||
$(window).scroll(function () {
|
||||
if ($("#post-list").length /* in Home page */
|
||||
|| postTitle.is(":hidden") /* is tab pages */
|
||||
|| topbarTitle.is(":hidden") /* not mobile screens */
|
||||
|| $("#sidebar.sidebar-expand").length) { /* when the sidebar trigger is clicked */
|
||||
return false;
|
||||
if ($pageTitle.length === 0 /* on Home page */
|
||||
|| $pageTitle.hasClass("dynamic-title")
|
||||
|| $topbarTitle.is(":hidden")) {/* not in mobile views */
|
||||
return;
|
||||
}
|
||||
|
||||
if ($(this).scrollTop() >= 95) {
|
||||
if (topbarTitle.text() !== title) {
|
||||
topbarTitle.text(title);
|
||||
}
|
||||
} else {
|
||||
if (topbarTitle.text() !== DEFAULT) {
|
||||
topbarTitle.text(DEFAULT);
|
||||
}
|
||||
}
|
||||
});
|
||||
const defaultTitleText = $topbarTitle.text().trim();
|
||||
let pageTitleText = $pageTitle.text().trim();
|
||||
let hasScrolled = false;
|
||||
let lastScrollTop = 0;
|
||||
|
||||
/* Click title remove hover effect. */
|
||||
topbarTitle.click(function() {
|
||||
$("body,html").animate({scrollTop: 0}, 800);
|
||||
});
|
||||
if ($("#page-category").length || $("#page-tag").length) {
|
||||
/* The title in Category or Tag page will be "<title> <count_of_posts>" */
|
||||
if (/\s/.test(pageTitleText)) {
|
||||
pageTitleText = pageTitleText.replace(/[0-9]/g, "").trim();
|
||||
}
|
||||
}
|
||||
|
||||
// When the page is scrolled down and then refreshed, the topbar title needs to be initialized
|
||||
if ($pageTitle.offset().top < $(window).scrollTop()) {
|
||||
$topbarTitle.text(pageTitleText);
|
||||
}
|
||||
|
||||
let options = {
|
||||
rootMargin: '-48px 0px 0px 0px', // 48px equals to the topbar height (3rem)
|
||||
threshold: [0, 1]
|
||||
};
|
||||
|
||||
let observer = new IntersectionObserver((entries) => {
|
||||
if (!hasScrolled) {
|
||||
hasScrolled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
let curScrollTop = $(window).scrollTop();
|
||||
let isScrollDown = lastScrollTop < curScrollTop;
|
||||
lastScrollTop = curScrollTop;
|
||||
let heading = entries[0];
|
||||
|
||||
if (isScrollDown) {
|
||||
if (heading.intersectionRatio === 0) {
|
||||
$topbarTitle.text(pageTitleText);
|
||||
}
|
||||
} else {
|
||||
if (heading.intersectionRatio === 1) {
|
||||
$topbarTitle.text(defaultTitleText);
|
||||
}
|
||||
}
|
||||
}, options);
|
||||
|
||||
observer.observe(document.querySelector(titleSelector));
|
||||
|
||||
/* Click title will scroll to top */
|
||||
$topbarTitle.click(function () {
|
||||
$("body,html").animate({scrollTop: 0}, 800);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* Chirpy v4.1.0 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* Chirpy v5.3.2 (https://github.com/cotes2020/jekyll-theme-chirpy/)
|
||||
* © 2019 Cotes Chung
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
/*
|
||||
/**
|
||||
* Tab 'Categories' expand/close effect.
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
const childPrefix = "l_";
|
||||
const parentPrefix = "h_";
|
||||
const collapse = $(".collapse");
|
||||
$(function () {
|
||||
const childPrefix = "l_";
|
||||
const parentPrefix = "h_";
|
||||
const collapse = $(".collapse");
|
||||
|
||||
/* close up top-category */
|
||||
collapse.on("hide.bs.collapse", function () { /* Bootstrap collapse events. */
|
||||
const parentId = parentPrefix + $(this).attr("id").substring(childPrefix.length);
|
||||
if (parentId) {
|
||||
$(`#${parentId} .far.fa-folder-open`).attr("class", "far fa-folder fa-fw");
|
||||
$(`#${parentId} i.fas`).addClass("rotate");
|
||||
$(`#${parentId}`).removeClass("hide-border-bottom");
|
||||
}
|
||||
});
|
||||
/* close up top-category */
|
||||
collapse.on("hide.bs.collapse", function () { /* Bootstrap collapse events. */
|
||||
const parentId = parentPrefix + $(this).attr("id").substring(childPrefix.length);
|
||||
if (parentId) {
|
||||
$(`#${parentId} .far.fa-folder-open`).attr("class", "far fa-folder fa-fw");
|
||||
$(`#${parentId} i.fas`).addClass("rotate");
|
||||
$(`#${parentId}`).removeClass("hide-border-bottom");
|
||||
}
|
||||
});
|
||||
|
||||
/* expand the top category */
|
||||
collapse.on("show.bs.collapse", function() {
|
||||
const parentId = parentPrefix + $(this).attr("id").substring(childPrefix.length);
|
||||
if (parentId) {
|
||||
$(`#${parentId} .far.fa-folder`).attr("class", "far fa-folder-open fa-fw");
|
||||
$(`#${parentId} i.fas`).removeClass("rotate");
|
||||
$(`#${parentId}`).addClass("hide-border-bottom");
|
||||
}
|
||||
});
|
||||
/* expand the top category */
|
||||
collapse.on("show.bs.collapse", function () {
|
||||
const parentId = parentPrefix + $(this).attr("id").substring(childPrefix.length);
|
||||
if (parentId) {
|
||||
$(`#${parentId} .far.fa-folder`).attr("class", "far fa-folder-open fa-fw");
|
||||
$(`#${parentId} i.fas`).removeClass("rotate");
|
||||
$(`#${parentId}`).addClass("hide-border-bottom");
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Create a more beautiful checkbox
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
/* hide browser default checkbox */
|
||||
$("input[type=checkbox]").addClass("unloaded");
|
||||
/* create checked checkbox */
|
||||
$("input[type=checkbox][checked]").before("<i class=\"fas fa-check-circle checked\"></i>");
|
||||
/* create normal checkbox */
|
||||
$("input[type=checkbox]:not([checked])").before("<i class=\"far fa-circle\"></i>");
|
||||
});
|
||||
133
_javascript/utils/clipboard.js
Normal file
133
_javascript/utils/clipboard.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Clipboard functions
|
||||
*
|
||||
* Dependencies:
|
||||
* - popper.js (https://github.com/popperjs/popper-core)
|
||||
* - clipboard.js (https://github.com/zenorocha/clipboard.js)
|
||||
*/
|
||||
|
||||
$(function () {
|
||||
const btnSelector = '.code-header>button';
|
||||
const ICON_SUCCESS = 'fas fa-check';
|
||||
const ATTR_TIMEOUT = 'timeout';
|
||||
const ATTR_TITLE_SUCCEED = 'data-title-succeed';
|
||||
const ATTR_TITLE_ORIGIN = 'data-original-title';
|
||||
const TIMEOUT = 2000; // in milliseconds
|
||||
|
||||
function isLocked(node) {
|
||||
if ($(node)[0].hasAttribute(ATTR_TIMEOUT)) {
|
||||
let timeout = $(node).attr(ATTR_TIMEOUT);
|
||||
if (Number(timeout) > Date.now()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function lock(node) {
|
||||
$(node).attr(ATTR_TIMEOUT, Date.now() + TIMEOUT);
|
||||
}
|
||||
|
||||
function unlock(node) {
|
||||
$(node).removeAttr(ATTR_TIMEOUT);
|
||||
}
|
||||
|
||||
/* --- Copy code block --- */
|
||||
|
||||
// Initial the clipboard.js object
|
||||
const clipboard = new ClipboardJS(btnSelector, {
|
||||
target(trigger) {
|
||||
let codeBlock = trigger.parentNode.nextElementSibling;
|
||||
return codeBlock.querySelector('code .rouge-code');
|
||||
}
|
||||
});
|
||||
|
||||
$(btnSelector).tooltip({
|
||||
trigger: 'hover',
|
||||
placement: 'left'
|
||||
});
|
||||
|
||||
function getIcon(btn) {
|
||||
let iconNode = $(btn).children();
|
||||
return iconNode.attr('class');
|
||||
}
|
||||
|
||||
const ICON_DEFAULT = getIcon(btnSelector);
|
||||
|
||||
function showTooltip(btn) {
|
||||
const succeedTitle = $(btn).attr(ATTR_TITLE_SUCCEED);
|
||||
$(btn).attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
|
||||
}
|
||||
|
||||
function hideTooltip(btn) {
|
||||
$(btn).tooltip('hide').removeAttr(ATTR_TITLE_ORIGIN);
|
||||
}
|
||||
|
||||
function setSuccessIcon(btn) {
|
||||
let btnNode = $(btn);
|
||||
let iconNode = btnNode.children();
|
||||
iconNode.attr('class', ICON_SUCCESS);
|
||||
}
|
||||
|
||||
function resumeIcon(btn) {
|
||||
let btnNode = $(btn);
|
||||
let iconNode = btnNode.children();
|
||||
iconNode.attr('class', ICON_DEFAULT);
|
||||
}
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
e.clearSelection();
|
||||
|
||||
const trigger = e.trigger;
|
||||
if (isLocked(trigger)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSuccessIcon(trigger);
|
||||
showTooltip(trigger);
|
||||
lock(trigger);
|
||||
|
||||
setTimeout(() => {
|
||||
hideTooltip(trigger);
|
||||
resumeIcon(trigger);
|
||||
unlock(trigger);
|
||||
}, TIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
/* --- Post link sharing --- */
|
||||
|
||||
$('#copy-link').click((e) => {
|
||||
|
||||
let target = $(e.target);
|
||||
|
||||
if (isLocked(target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy URL to clipboard
|
||||
|
||||
const url = window.location.href;
|
||||
const $temp = $("<input>");
|
||||
|
||||
$("body").append($temp);
|
||||
$temp.val(url).select();
|
||||
document.execCommand("copy");
|
||||
$temp.remove();
|
||||
|
||||
// Switch tooltip title
|
||||
|
||||
const defaultTitle = target.attr(ATTR_TITLE_ORIGIN);
|
||||
const succeedTitle = target.attr(ATTR_TITLE_SUCCEED);
|
||||
|
||||
target.attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
|
||||
lock(target);
|
||||
|
||||
setTimeout(() => {
|
||||
target.attr(ATTR_TITLE_ORIGIN, defaultTitle);
|
||||
unlock(target);
|
||||
}, TIMEOUT);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copy current page url to clipboard.
|
||||
*/
|
||||
|
||||
function copyLink(url, msg) {
|
||||
if (!url || 0 === url.length) {
|
||||
url = window.location.href;
|
||||
}
|
||||
|
||||
const $temp = $("<input>");
|
||||
$("body").append($temp);
|
||||
$temp.val(url).select();
|
||||
document.execCommand("copy");
|
||||
$temp.remove();
|
||||
|
||||
let feedback = "Link copied successfully!";
|
||||
if (msg && msg.length > 0) {
|
||||
feedback = msg;
|
||||
}
|
||||
|
||||
alert(feedback);
|
||||
}
|
||||
@@ -1,47 +1,46 @@
|
||||
/**
|
||||
Lazy load images (https://github.com/ApoorvSaxena/lozad.js)
|
||||
and popup when clicked (https://github.com/dimsemenov/Magnific-Popup)
|
||||
*/
|
||||
Lazy load images (https://github.com/ApoorvSaxena/lozad.js)
|
||||
and popup when clicked (https://github.com/dimsemenov/Magnific-Popup)
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
$(function () {
|
||||
const IMG_SCOPE = '#main > div.row:first-child > div:first-child';
|
||||
|
||||
const IMG_SCOPE = '#main > div.row:first-child > div:first-child';
|
||||
|
||||
if ($(`${IMG_SCOPE} img`).length <= 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* lazy loading */
|
||||
|
||||
const imgList = document.querySelectorAll(`${IMG_SCOPE} img[data-src]`);
|
||||
const observer = lozad(imgList);
|
||||
observer.observe();
|
||||
|
||||
/* popup */
|
||||
|
||||
$(`${IMG_SCOPE} p > img[data-src],${IMG_SCOPE} img[data-src].preview-img`).each(
|
||||
function() {
|
||||
let nextTag = $(this).next();
|
||||
const title = nextTag.prop('tagName') === 'EM' ? nextTag.text() : '';
|
||||
const src = $(this).attr('data-src'); // created by lozad.js
|
||||
|
||||
$(this).wrap(`<a href="${src}" title="${title}" class="popup"></a>`);
|
||||
if ($(`${IMG_SCOPE} img`).length <= 0) {
|
||||
return;
|
||||
}
|
||||
);
|
||||
|
||||
$('.popup').magnificPopup({
|
||||
type: 'image',
|
||||
closeOnContentClick: true,
|
||||
showCloseBtn: false,
|
||||
zoom: {
|
||||
enabled: true,
|
||||
duration: 300,
|
||||
easing: 'ease-in-out'
|
||||
}
|
||||
});
|
||||
/* lazy loading */
|
||||
|
||||
/* markup the image links */
|
||||
const imgList = document.querySelectorAll(`${IMG_SCOPE} img[data-src]`);
|
||||
const observer = lozad(imgList);
|
||||
observer.observe();
|
||||
|
||||
$(`${IMG_SCOPE} a`).has('img').addClass('img-link');
|
||||
/* popup */
|
||||
|
||||
$(`${IMG_SCOPE} p > img[data-src], ${IMG_SCOPE} img[data-src].preview-img`).each(
|
||||
function () {
|
||||
let nextTag = $(this).next();
|
||||
const title = nextTag.prop('tagName') === 'EM' ? nextTag.text() : '';
|
||||
const src = $(this).attr('data-src'); // created by lozad.js
|
||||
|
||||
$(this).wrap(`<a href="${src}" title="${title}" class="popup"></a>`);
|
||||
}
|
||||
);
|
||||
|
||||
$('.popup').magnificPopup({
|
||||
type: 'image',
|
||||
closeOnContentClick: true,
|
||||
showCloseBtn: false,
|
||||
zoom: {
|
||||
enabled: true,
|
||||
duration: 300,
|
||||
easing: 'ease-in-out'
|
||||
}
|
||||
});
|
||||
|
||||
/* markup the image links */
|
||||
|
||||
$(`${IMG_SCOPE} a`).has('img').addClass('img-link');
|
||||
|
||||
});
|
||||
|
||||
43
_javascript/utils/locale-datetime.js
Normal file
43
_javascript/utils/locale-datetime.js
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Update month/day to locale datetime
|
||||
*
|
||||
* Requirement: <https://github.com/iamkun/dayjs>
|
||||
*/
|
||||
|
||||
/* A tool for locale datetime */
|
||||
const LocaleHelper = (function () {
|
||||
const locale = $('html').attr('lang').substr(0, 2);
|
||||
const attrTimestamp = 'data-ts';
|
||||
const attrDateFormat = 'data-df';
|
||||
|
||||
return {
|
||||
locale: () => locale,
|
||||
attrTimestamp: () => attrTimestamp,
|
||||
attrDateFormat: () => attrDateFormat,
|
||||
getTimestamp: ($elem) => Number($elem.attr(attrTimestamp)), // unix timestamp
|
||||
getDateFormat: ($elem) => $elem.attr(attrDateFormat)
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
$(function () {
|
||||
dayjs.locale(LocaleHelper.locale());
|
||||
dayjs.extend(window.dayjs_plugin_localizedFormat);
|
||||
|
||||
$(`[${LocaleHelper.attrTimestamp()}]`).each(function () {
|
||||
const date = dayjs.unix(LocaleHelper.getTimestamp($(this)));
|
||||
const text = date.format(LocaleHelper.getDateFormat($(this)));
|
||||
$(this).text(text);
|
||||
$(this).removeAttr(LocaleHelper.attrTimestamp());
|
||||
$(this).removeAttr(LocaleHelper.attrDateFormat());
|
||||
|
||||
// setup tooltips
|
||||
const tooltip = $(this).attr('data-toggle');
|
||||
if (typeof tooltip === 'undefined' || tooltip !== 'tooltip') {
|
||||
return;
|
||||
}
|
||||
|
||||
const tooltipText = date.format('llll'); // see: https://day.js.org/docs/en/display/format#list-of-localized-formats
|
||||
$(this).attr('data-original-title', tooltipText);
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/**
|
||||
* Count page views form GA or local cache file.
|
||||
*
|
||||
* Dependencies:
|
||||
@@ -7,244 +7,244 @@
|
||||
*/
|
||||
|
||||
const getInitStatus = (function () {
|
||||
let hasInit = false;
|
||||
return () => {
|
||||
let ret = hasInit;
|
||||
if (!hasInit) {
|
||||
hasInit = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
let hasInit = false;
|
||||
return () => {
|
||||
let ret = hasInit;
|
||||
if (!hasInit) {
|
||||
hasInit = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}());
|
||||
|
||||
const PvOpts = (function () {
|
||||
function getContent(selector) {
|
||||
return $(selector).attr("content");
|
||||
}
|
||||
|
||||
function hasContent(selector) {
|
||||
let content = getContent(selector);
|
||||
return (typeof content !== "undefined" && content !== false);
|
||||
}
|
||||
|
||||
return {
|
||||
getProxyMeta() {
|
||||
return getContent("meta[name=pv-proxy-endpoint]");
|
||||
},
|
||||
getLocalMeta() {
|
||||
return getContent("meta[name=pv-cache-path]");
|
||||
},
|
||||
hasProxyMeta() {
|
||||
return hasContent("meta[name=pv-proxy-endpoint]");
|
||||
},
|
||||
hasLocalMeta() {
|
||||
return hasContent("meta[name=pv-cache-path]");
|
||||
function getContent(selector) {
|
||||
return $(selector).attr("content");
|
||||
}
|
||||
};
|
||||
|
||||
function hasContent(selector) {
|
||||
let content = getContent(selector);
|
||||
return (typeof content !== "undefined" && content !== false);
|
||||
}
|
||||
|
||||
return {
|
||||
getProxyMeta() {
|
||||
return getContent("meta[name=pv-proxy-endpoint]");
|
||||
},
|
||||
getLocalMeta() {
|
||||
return getContent("meta[name=pv-cache-path]");
|
||||
},
|
||||
hasProxyMeta() {
|
||||
return hasContent("meta[name=pv-proxy-endpoint]");
|
||||
},
|
||||
hasLocalMeta() {
|
||||
return hasContent("meta[name=pv-cache-path]");
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
||||
|
||||
const PvStorage = (function () {
|
||||
const Keys = {
|
||||
KEY_PV: "pv",
|
||||
KEY_PV_SRC: "pv_src",
|
||||
KEY_CREATION: "pv_created_date"
|
||||
};
|
||||
const Keys = {
|
||||
KEY_PV: "pv",
|
||||
KEY_PV_SRC: "pv_src",
|
||||
KEY_CREATION: "pv_created_date"
|
||||
};
|
||||
|
||||
const Source = {
|
||||
LOCAL: "same-origin",
|
||||
PROXY: "cors"
|
||||
};
|
||||
const Source = {
|
||||
LOCAL: "same-origin",
|
||||
PROXY: "cors"
|
||||
};
|
||||
|
||||
function get(key) {
|
||||
return localStorage.getItem(key);
|
||||
}
|
||||
|
||||
function set(key, val) {
|
||||
localStorage.setItem(key, val);
|
||||
}
|
||||
|
||||
function saveCache(pv, src) {
|
||||
set(Keys.KEY_PV, pv);
|
||||
set(Keys.KEY_PV_SRC, src);
|
||||
set(Keys.KEY_CREATION, new Date().toJSON());
|
||||
}
|
||||
|
||||
return {
|
||||
keysCount() {
|
||||
return Object.keys(Keys).length;
|
||||
},
|
||||
hasCache() {
|
||||
return (localStorage.getItem(Keys.KEY_PV) !== null);
|
||||
},
|
||||
getCache() {
|
||||
return JSON.parse(localStorage.getItem(Keys.KEY_PV));
|
||||
},
|
||||
saveLocalCache(pv) {
|
||||
saveCache(pv, Source.LOCAL);
|
||||
},
|
||||
saveProxyCache(pv) {
|
||||
saveCache(pv, Source.PROXY);
|
||||
},
|
||||
isExpired() {
|
||||
let date = new Date(get(Keys.KEY_CREATION));
|
||||
date.setHours(date.getHours() + 1); // per hour
|
||||
return Date.now() >= date.getTime();
|
||||
},
|
||||
isFromLocal() {
|
||||
return get(Keys.KEY_PV_SRC) === Source.LOCAL;
|
||||
},
|
||||
isFromProxy() {
|
||||
return get(Keys.KEY_PV_SRC) === Source.PROXY;
|
||||
},
|
||||
newerThan(pv) {
|
||||
return PvStorage.getCache().totalsForAllResults["ga:pageviews"] > pv.totalsForAllResults["ga:pageviews"];
|
||||
},
|
||||
inspectKeys() {
|
||||
if (localStorage.length !== PvStorage.keysCount()) {
|
||||
localStorage.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
for(let i = 0; i < localStorage.length; i++){
|
||||
const key = localStorage.key(i);
|
||||
switch (key) {
|
||||
case Keys.KEY_PV:
|
||||
case Keys.KEY_PV_SRC:
|
||||
case Keys.KEY_CREATION:
|
||||
break;
|
||||
default:
|
||||
localStorage.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
function get(key) {
|
||||
return localStorage.getItem(key);
|
||||
}
|
||||
};
|
||||
|
||||
function set(key, val) {
|
||||
localStorage.setItem(key, val);
|
||||
}
|
||||
|
||||
function saveCache(pv, src) {
|
||||
set(Keys.KEY_PV, pv);
|
||||
set(Keys.KEY_PV_SRC, src);
|
||||
set(Keys.KEY_CREATION, new Date().toJSON());
|
||||
}
|
||||
|
||||
return {
|
||||
keysCount() {
|
||||
return Object.keys(Keys).length;
|
||||
},
|
||||
hasCache() {
|
||||
return (localStorage.getItem(Keys.KEY_PV) !== null);
|
||||
},
|
||||
getCache() {
|
||||
return JSON.parse(localStorage.getItem(Keys.KEY_PV));
|
||||
},
|
||||
saveLocalCache(pv) {
|
||||
saveCache(pv, Source.LOCAL);
|
||||
},
|
||||
saveProxyCache(pv) {
|
||||
saveCache(pv, Source.PROXY);
|
||||
},
|
||||
isExpired() {
|
||||
let date = new Date(get(Keys.KEY_CREATION));
|
||||
date.setHours(date.getHours() + 1); // per hour
|
||||
return Date.now() >= date.getTime();
|
||||
},
|
||||
isFromLocal() {
|
||||
return get(Keys.KEY_PV_SRC) === Source.LOCAL;
|
||||
},
|
||||
isFromProxy() {
|
||||
return get(Keys.KEY_PV_SRC) === Source.PROXY;
|
||||
},
|
||||
newerThan(pv) {
|
||||
return PvStorage.getCache().totalsForAllResults["ga:pageviews"] > pv.totalsForAllResults["ga:pageviews"];
|
||||
},
|
||||
inspectKeys() {
|
||||
if (localStorage.length !== PvStorage.keysCount()) {
|
||||
localStorage.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
switch (key) {
|
||||
case Keys.KEY_PV:
|
||||
case Keys.KEY_PV_SRC:
|
||||
case Keys.KEY_CREATION:
|
||||
break;
|
||||
default:
|
||||
localStorage.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}()); /* PvStorage */
|
||||
|
||||
function countUp(min, max, destId) {
|
||||
if (min < max) {
|
||||
let numAnim = new CountUp(destId, min, max);
|
||||
if (!numAnim.error) {
|
||||
numAnim.start();
|
||||
} else {
|
||||
console.error(numAnim.error);
|
||||
if (min < max) {
|
||||
let numAnim = new CountUp(destId, min, max);
|
||||
if (!numAnim.error) {
|
||||
numAnim.start();
|
||||
} else {
|
||||
console.error(numAnim.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function countPV(path, rows) {
|
||||
let count = 0;
|
||||
let count = 0;
|
||||
|
||||
if (typeof rows !== "undefined" ) {
|
||||
for (let i = 0; i < rows.length; ++i) {
|
||||
const gaPath = rows[parseInt(i, 10)][0];
|
||||
if (gaPath === path) { /* path format see: site.permalink */
|
||||
count += parseInt(rows[parseInt(i, 10)][1], 10);
|
||||
break;
|
||||
}
|
||||
if (typeof rows !== "undefined") {
|
||||
for (let i = 0; i < rows.length; ++i) {
|
||||
const gaPath = rows[parseInt(i, 10)][0];
|
||||
if (gaPath === path) { /* path format see: site.permalink */
|
||||
count += parseInt(rows[parseInt(i, 10)][1], 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
return count;
|
||||
}
|
||||
|
||||
function tacklePV(rows, path, elem, hasInit) {
|
||||
let count = countPV(path, rows);
|
||||
count = (count === 0 ? 1 : count);
|
||||
let count = countPV(path, rows);
|
||||
count = (count === 0 ? 1 : count);
|
||||
|
||||
if (!hasInit) {
|
||||
elem.text(new Intl.NumberFormat().format(count));
|
||||
} else {
|
||||
const initCount = parseInt(elem.text().replace(/,/g, ""), 10);
|
||||
if (count > initCount) {
|
||||
countUp(initCount, count, elem.attr("id"));
|
||||
if (!hasInit) {
|
||||
elem.text(new Intl.NumberFormat().format(count));
|
||||
} else {
|
||||
const initCount = parseInt(elem.text().replace(/,/g, ""), 10);
|
||||
if (count > initCount) {
|
||||
countUp(initCount, count, elem.attr("id"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function displayPageviews(data) {
|
||||
if (typeof data === "undefined") {
|
||||
return;
|
||||
}
|
||||
if (typeof data === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
let hasInit = getInitStatus();
|
||||
const rows = data.rows; /* could be undefined */
|
||||
let hasInit = getInitStatus();
|
||||
const rows = data.rows; /* could be undefined */
|
||||
|
||||
if ($("#post-list").length > 0) { /* the Home page */
|
||||
$(".post-preview").each(function() {
|
||||
const path = $(this).find("a").attr("href");
|
||||
tacklePV(rows, path, $(this).find(".pageviews"), hasInit);
|
||||
});
|
||||
if ($("#post-list").length > 0) { /* the Home page */
|
||||
$(".post-preview").each(function () {
|
||||
const path = $(this).find("a").attr("href");
|
||||
tacklePV(rows, path, $(this).find(".pageviews"), hasInit);
|
||||
});
|
||||
|
||||
} else if ($(".post").length > 0) { /* the post */
|
||||
const path = window.location.pathname;
|
||||
tacklePV(rows, path, $("#pv"), hasInit);
|
||||
}
|
||||
} else if ($(".post").length > 0) { /* the post */
|
||||
const path = window.location.pathname;
|
||||
tacklePV(rows, path, $("#pv"), hasInit);
|
||||
}
|
||||
}
|
||||
|
||||
function fetchProxyPageviews() {
|
||||
if (PvOpts.hasProxyMeta()) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: PvOpts.getProxyMeta(),
|
||||
dataType: "jsonp",
|
||||
jsonpCallback: "displayPageviews",
|
||||
success: (data) => {
|
||||
PvStorage.saveProxyCache(JSON.stringify(data));
|
||||
},
|
||||
error: (jqXHR, textStatus, errorThrown) => {
|
||||
console.log("Failed to load pageviews from proxy server: " + errorThrown);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (PvOpts.hasProxyMeta()) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: PvOpts.getProxyMeta(),
|
||||
dataType: "jsonp",
|
||||
jsonpCallback: "displayPageviews",
|
||||
success: (data) => {
|
||||
PvStorage.saveProxyCache(JSON.stringify(data));
|
||||
},
|
||||
error: (jqXHR, textStatus, errorThrown) => {
|
||||
console.log("Failed to load pageviews from proxy server: " + errorThrown);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function fetchLocalPageviews(hasCache = false) {
|
||||
return fetch(PvOpts.getLocalMeta())
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (hasCache) {
|
||||
// The cache from the proxy will sometimes be more recent than the local one
|
||||
if (PvStorage.isFromProxy() && PvStorage.newerThan(data)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
displayPageviews(data);
|
||||
PvStorage.saveLocalCache(JSON.stringify(data));
|
||||
});
|
||||
return fetch(PvOpts.getLocalMeta())
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (hasCache) {
|
||||
// The cache from the proxy will sometimes be more recent than the local one
|
||||
if (PvStorage.isFromProxy() && PvStorage.newerThan(data)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
displayPageviews(data);
|
||||
PvStorage.saveLocalCache(JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
$(function() {
|
||||
if ($(".pageviews").length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
PvStorage.inspectKeys();
|
||||
|
||||
if (PvStorage.hasCache()) {
|
||||
displayPageviews(PvStorage.getCache());
|
||||
|
||||
if (PvStorage.isExpired()) {
|
||||
if (PvOpts.hasLocalMeta()) {
|
||||
fetchLocalPageviews(true).then(fetchProxyPageviews);
|
||||
} else {
|
||||
fetchProxyPageviews();
|
||||
}
|
||||
|
||||
} else {
|
||||
if (PvStorage.isFromLocal()) {
|
||||
fetchProxyPageviews();
|
||||
}
|
||||
$(function () {
|
||||
if ($(".pageviews").length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
} else { // no cached
|
||||
PvStorage.inspectKeys();
|
||||
|
||||
if (PvOpts.hasLocalMeta()) {
|
||||
fetchLocalPageviews().then(fetchProxyPageviews);
|
||||
} else {
|
||||
fetchProxyPageviews();
|
||||
if (PvStorage.hasCache()) {
|
||||
displayPageviews(PvStorage.getCache());
|
||||
|
||||
if (PvStorage.isExpired()) {
|
||||
if (PvOpts.hasLocalMeta()) {
|
||||
fetchLocalPageviews(true).then(fetchProxyPageviews);
|
||||
} else {
|
||||
fetchProxyPageviews();
|
||||
}
|
||||
|
||||
} else {
|
||||
if (PvStorage.isFromLocal()) {
|
||||
fetchProxyPageviews();
|
||||
}
|
||||
}
|
||||
|
||||
} else { // no cached
|
||||
|
||||
if (PvOpts.hasLocalMeta()) {
|
||||
fetchLocalPageviews().then(fetchProxyPageviews);
|
||||
} else {
|
||||
fetchProxyPageviews();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -1,81 +1,96 @@
|
||||
/*
|
||||
Safari doesn't support CSS `scroll-behavior: smooth`,
|
||||
so here is a compatible solution for all browser to smooth scrolling
|
||||
/**
|
||||
Safari doesn't support CSS `scroll-behavior: smooth`,
|
||||
so here is a compatible solution for all browser to smooth scrolling
|
||||
|
||||
See: <https://css-tricks.com/snippets/jquery/smooth-scrolling/>
|
||||
See: <https://css-tricks.com/snippets/jquery/smooth-scrolling/>
|
||||
|
||||
Warning: It must be called after all `<a>` tags (e.g., the dynamic TOC) are ready.
|
||||
*/
|
||||
Warning: It must be called after all `<a>` tags (e.g., the dynamic TOC) are ready.
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
$("a[href*='#']")
|
||||
.not("[href='#']")
|
||||
.not("[href='#0']")
|
||||
.click(function(event) {
|
||||
$(function () {
|
||||
const $topbarTitle = $("#topbar-title");
|
||||
const REM = 16; // in pixels
|
||||
const ATTR_SCROLL_FOCUS = "scroll-focus";
|
||||
|
||||
if (this.pathname.replace(/^\//, "") === location.pathname.replace(/^\//, "")) {
|
||||
if (location.hostname === this.hostname) {
|
||||
$("a[href*='#']")
|
||||
.not("[href='#']")
|
||||
.not("[href='#0']")
|
||||
.click(function (event) {
|
||||
if (this.pathname.replace(/^\//, "") !==
|
||||
location.pathname.replace(/^\//, "")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const REM = 16; /* 16px */
|
||||
if (location.hostname !== this.hostname) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hash = decodeURI(this.hash);
|
||||
let isFnRef = RegExp(/^#fnref:/).test(hash);
|
||||
let isFn = RegExp(/^#fn:/).test(hash);
|
||||
let selector = hash.includes(":") ? hash.replace(/\:/, "\\:") : hash;
|
||||
let target = $(selector);
|
||||
const hash = decodeURI(this.hash);
|
||||
let toFootnoteRef = RegExp(/^#fnref:/).test(hash);
|
||||
let toFootnote = toFootnoteRef ? false : RegExp(/^#fn:/).test(hash);
|
||||
let selector = hash.includes(":") ? hash.replace(/:/g, "\\:") : hash;
|
||||
let $target = $(selector);
|
||||
|
||||
let isMobileViews = $topbarTitle.is(":visible");
|
||||
let isPortrait = $(window).width() < $(window).height();
|
||||
|
||||
if (typeof $target === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.length) {
|
||||
event.preventDefault();
|
||||
|
||||
if (history.pushState) { /* add hash to URL */
|
||||
history.pushState(null, null, hash);
|
||||
history.pushState(null, null, hash);
|
||||
}
|
||||
|
||||
let curOffset = $(this).offset().top;
|
||||
let destOffset = target.offset().top;
|
||||
const scrollUp = (destOffset < curOffset);
|
||||
const topbarHeight = $("#topbar-wrapper").outerHeight();
|
||||
let curOffset = $(window).scrollTop();
|
||||
let destOffset = $target.offset().top -= REM / 2;
|
||||
|
||||
if (scrollUp && isFnRef) {
|
||||
/* Avoid the top-bar covering `fnref` when scrolling up
|
||||
because `fnref` has no `%anchor`(see: module.scss) style. */
|
||||
destOffset -= (topbarHeight + REM / 2);
|
||||
if (destOffset < curOffset) { // scroll up
|
||||
ScrollHelper.hideTopbar();
|
||||
ScrollHelper.addScrollUpTask();
|
||||
|
||||
if (isMobileViews && isPortrait) {
|
||||
destOffset -= ScrollHelper.getTopbarHeight();
|
||||
}
|
||||
|
||||
} else { // scroll down
|
||||
if (isMobileViews && isPortrait) {
|
||||
destOffset -= ScrollHelper.getTopbarHeight();
|
||||
}
|
||||
}
|
||||
|
||||
$("html,body").animate({
|
||||
scrollTop: destOffset
|
||||
}, 800, () => {
|
||||
$("html").animate({
|
||||
scrollTop: destOffset
|
||||
}, 500, () => {
|
||||
$target.focus();
|
||||
|
||||
const $target = $(target);
|
||||
$target.focus();
|
||||
/* clean up old scroll mark */
|
||||
if ($(`[${ATTR_SCROLL_FOCUS}=true]`).length) {
|
||||
$(`[${ATTR_SCROLL_FOCUS}=true]`).attr(ATTR_SCROLL_FOCUS, false);
|
||||
}
|
||||
|
||||
const SCROLL_MARK = "scroll-focus";
|
||||
/* Clean :target links */
|
||||
if ($(":target").length) { /* element that visited by the URL with hash */
|
||||
$(":target").attr(ATTR_SCROLL_FOCUS, false);
|
||||
}
|
||||
|
||||
/* clean up old scroll mark */
|
||||
if ($(`[${SCROLL_MARK}=true]`).length) {
|
||||
$(`[${SCROLL_MARK}=true]`).attr(SCROLL_MARK, false);
|
||||
}
|
||||
/* set scroll mark to footnotes */
|
||||
if (toFootnote || toFootnoteRef) {
|
||||
$target.attr(ATTR_SCROLL_FOCUS, true);
|
||||
}
|
||||
|
||||
/* Clean :target links */
|
||||
if ($(":target").length) { /* element that visited by the URL with hash */
|
||||
$(":target").attr(SCROLL_MARK, false);
|
||||
}
|
||||
if ($target.is(":focus")) { /* Checking if the target was focused */
|
||||
return false;
|
||||
} else {
|
||||
$target.attr("tabindex", "-1"); /* Adding tabindex for elements not focusable */
|
||||
$target.focus(); /* Set focus again */
|
||||
}
|
||||
|
||||
/* set scroll mark to footnotes */
|
||||
if (isFn || isFnRef) {
|
||||
$target.attr(SCROLL_MARK, true);
|
||||
}
|
||||
|
||||
if ($target.is(":focus")) { /* Checking if the target was focused */
|
||||
return false;
|
||||
} else {
|
||||
$target.attr("tabindex", "-1"); /* Adding tabindex for elements not focusable */
|
||||
$target.focus(); /* Set focus again */
|
||||
}
|
||||
if (ScrollHelper.hasScrollUpTask()) {
|
||||
ScrollHelper.popScrollUpTask();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}); /* click() */
|
||||
}); /* click() */
|
||||
});
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Calculate the Timeago
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
|
||||
const timeagoElem = $(".timeago");
|
||||
|
||||
let toRefresh = timeagoElem.length;
|
||||
|
||||
let intervalId = void 0;
|
||||
|
||||
const locale = $("meta[name=layout-lang]").attr("content");
|
||||
const dPrompt = $("meta[name=day-prompt]").attr("content");
|
||||
const hrPrompt = $("meta[name=hour-prompt]").attr("content");
|
||||
const minPrompt = $("meta[name=minute-prompt]").attr("content");
|
||||
const justnowPrompt = $("meta[name=justnow-prompt]").attr("content");
|
||||
|
||||
function timeago(isoDate, dateStr) {
|
||||
let now = new Date();
|
||||
let past = new Date(isoDate);
|
||||
|
||||
if (past.getFullYear() !== now.getFullYear()
|
||||
|| past.getMonth() !== now.getMonth()) {
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
let seconds = Math.floor((now - past) / 1000);
|
||||
|
||||
let day = Math.floor(seconds / 86400);
|
||||
if (day >= 1) {
|
||||
toRefresh -= 1;
|
||||
return ` ${day} ${dPrompt}`;
|
||||
}
|
||||
|
||||
let hour = Math.floor(seconds / 3600);
|
||||
if (hour >= 1) {
|
||||
return ` ${hour} ${hrPrompt}`;
|
||||
}
|
||||
|
||||
let minute = Math.floor(seconds / 60);
|
||||
if (minute >= 1) {
|
||||
return ` ${minute} ${minPrompt}`;
|
||||
}
|
||||
|
||||
return justnowPrompt;
|
||||
}
|
||||
|
||||
function updateTimeago() {
|
||||
$(".timeago").each(function() {
|
||||
if ($(this).children("i").length > 0) {
|
||||
let dateStr = $(this).clone().children().remove().end().text();
|
||||
let node = $(this).children("i");
|
||||
let iosDate = node.text(); /* ISO Date: "YYYY-MM-DDTHH:MM:SSZ" */
|
||||
$(this).text(timeago(iosDate, dateStr));
|
||||
$(this).append(node);
|
||||
}
|
||||
});
|
||||
|
||||
if (toRefresh === 0 && typeof intervalId !== "undefined") {
|
||||
clearInterval(intervalId); /* stop interval */
|
||||
}
|
||||
return toRefresh;
|
||||
}
|
||||
|
||||
if (toRefresh === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateTimeago() > 0) { /* run immediately */
|
||||
intervalId = setInterval(updateTimeago, 60000); /* run every minute */
|
||||
}
|
||||
|
||||
});
|
||||
@@ -3,35 +3,32 @@ layout: page
|
||||
# The Archives of posts.
|
||||
---
|
||||
|
||||
<div id="archives" class="pl-xl-2">
|
||||
{% assign df_strftime_m = site.data.locales[site.lang].df.archives.strftime | default: '/ %m' %}
|
||||
{% assign df_dayjs_m = site.data.locales[site.lang].df.archives.dayjs | default: '/ MM' %}
|
||||
|
||||
<div id="archives" class="pl-xl-3">
|
||||
|
||||
{% for post in site.posts %}
|
||||
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
|
||||
{% capture pre_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}
|
||||
{% if forloop.first %}
|
||||
{% assign last_day = "" %}
|
||||
{% assign last_month = "" %}
|
||||
<span class="lead">{{this_year}}</span>
|
||||
<ul class="list-unstyled">
|
||||
{% endif %}
|
||||
<li>
|
||||
<div>
|
||||
{% capture this_day %}{{ post.date | date: "%d" }}{% endcapture %}
|
||||
{% capture _mth_df %}{{ site.data.locales[site.lang].date_format.post.archive_month | default: "%b" }}{% endcapture %}
|
||||
{% capture this_month %}{{ post.date | date: _mth_df }}{% endcapture %}
|
||||
<span class="date day">{{ this_day }}</span>
|
||||
<span class="date month small text-muted">{% include no-zero-date.html date_str=this_month %}</span>
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% if forloop.last %}
|
||||
</ul>
|
||||
{% elsif this_year != pre_year %}
|
||||
</ul>
|
||||
<span class="lead">{{pre_year}}</span>
|
||||
<ul class="list-unstyled">
|
||||
{% assign last_day = "" %}
|
||||
{% assign last_month = "" %}
|
||||
{% capture cur_year %}{{ post.date | date: "%Y" }}{% endcapture %}
|
||||
|
||||
{% if cur_year != last_year %}
|
||||
{% unless forloop.first %}</ul>{% endunless %}
|
||||
<div class="year lead">{{ cur_year }}</div>
|
||||
<ul class="list-unstyled">
|
||||
{% assign last_year = cur_year %}
|
||||
{% endif %}
|
||||
|
||||
<li>
|
||||
{% assign ts = post.date | date: '%s' %}
|
||||
<span class="date day" data-ts="{{ ts }}" data-df="DD">{{ post.date | date: "%d" }}</span>
|
||||
<span class="date month small text-muted ml-1" data-ts="{{ ts }}" data-df="{{ df_dayjs_m }}">
|
||||
{{ post.date | date: df_strftime_m }}
|
||||
</span>
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
</li>
|
||||
|
||||
{% if forloop.last %}</ul>{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -45,10 +45,24 @@ layout: page
|
||||
<span class="text-muted small font-weight-light">
|
||||
{% if sub_categories_size > 0 %}
|
||||
{{ sub_categories_size }}
|
||||
{{ site.data.locales[site.lang].categories.category_measure | default: 'categories' }},
|
||||
{% if sub_categories_size > 1 %}
|
||||
{{ site.data.locales[site.lang].categories.category_measure.plural
|
||||
| default: site.data.locales[site.lang].categories.category_measure }}
|
||||
{% else %}
|
||||
{{ site.data.locales[site.lang].categories.category_measure.singular
|
||||
| default: site.data.locales[site.lang].categories.category_measure }}
|
||||
{% endif %},
|
||||
{% endif %}
|
||||
|
||||
{{ top_posts_size }}
|
||||
|
||||
{% if top_posts_size > 1 %}
|
||||
{{ site.data.locales[site.lang].categories.post_measure.plural
|
||||
| default: site.data.locales[site.lang].categories.post_measure }}
|
||||
{% else %}
|
||||
{{ site.data.locales[site.lang].categories.post_measure.singular
|
||||
| default: site.data.locales[site.lang].categories.post_measure }}
|
||||
{% endif %}
|
||||
{{ top_posts_size }}
|
||||
{{ site.data.locales[site.lang].categories.post_measure | default: 'posts' }}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@@ -81,7 +95,14 @@ layout: page
|
||||
{% assign posts_size = site.categories[sub_category] | size %}
|
||||
<span class="text-muted small font-weight-light">
|
||||
{{ posts_size }}
|
||||
{{ site.data.locales[site.lang].categories.post_measure | default: 'posts' }}
|
||||
|
||||
{% if posts_size > 1 %}
|
||||
{{ site.data.locales[site.lang].categories.post_measure.plural
|
||||
| default: site.data.locales[site.lang].categories.post_measure }}
|
||||
{% else %}
|
||||
{{ site.data.locales[site.lang].categories.post_measure.singular
|
||||
| default: site.data.locales[site.lang].categories.post_measure }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
||||
@@ -11,13 +11,11 @@ layout: page
|
||||
</h1>
|
||||
|
||||
<ul class="post-content pl-0">
|
||||
{% assign post_df = site.data.locales[site.lang].date_format.post.long | default: '%b %e, %Y' %}
|
||||
|
||||
{% for post in page.posts %}
|
||||
<li class="d-flex justify-content-between pl-md-3 pr-md-3">
|
||||
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
|
||||
<span class="dash flex-grow-1"></span>
|
||||
<span class="text-muted small">{{ post.date | date: post_df }}</span>
|
||||
{% include datetime.html date=post.date wrap='span' class='text-muted small' %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
@@ -5,35 +5,36 @@ layout: compress
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
{% include assets-origin.html %}
|
||||
|
||||
{% capture prefer_mode %}
|
||||
{% if site.theme_mode %}
|
||||
mode="{{ site.theme_mode }}"
|
||||
data-mode="{{ site.theme_mode }}"
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
|
||||
<html lang="{{ site.content_lang | default: site.lang }}" {{ prefer_mode }}>
|
||||
<!-- `site.alt_lang` can specify a language different from the UI -->
|
||||
<html lang="{{ site.alt_lang | default: site.lang }}"{{ prefer_mode }}>
|
||||
|
||||
{% include head.html %}
|
||||
|
||||
<body data-spy="scroll" data-target="#toc">
|
||||
<body data-spy="scroll" data-target="#toc" data-topbar-visible="true">
|
||||
|
||||
{% include sidebar.html %}
|
||||
|
||||
{% include topbar.html %}
|
||||
|
||||
<div id="main-wrapper">
|
||||
<div id="main">
|
||||
|
||||
{% include refactor-content.html content=content %}
|
||||
|
||||
{% include footer.html %}
|
||||
|
||||
<div id="main-wrapper" class="d-flex justify-content-center">
|
||||
<div id="main" class="container pl-xl-4 pr-xl-4">
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
{% include search-results.html %}
|
||||
|
||||
</div> <!-- #main-wrapper -->
|
||||
|
||||
{% include footer.html %}
|
||||
|
||||
{% if page.mermaid %}
|
||||
{% include mermaid.html %}
|
||||
{% endif %}
|
||||
@@ -44,6 +45,23 @@ layout: compress
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
{% if site.pwa.enabled %}
|
||||
<div id="notification" class="toast" role="alert" aria-live="assertive" aria-atomic="true"
|
||||
data-animation="true" data-autohide="false">
|
||||
<div class="toast-header">
|
||||
<button type="button" class="ml-2 ml-auto close" data-dismiss="toast" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="toast-body text-center pt-0">
|
||||
<p class="pl-2 pr-2 mb-3">{{ site.data.locales[site.lang].notification.update_found }}</p>
|
||||
<button type="button" class="btn btn-primary" aria-label="Update">
|
||||
{{ site.data.locales[site.lang].notification.update }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% include search-loader.html %}
|
||||
|
||||
{% include js-selector.html %}
|
||||
|
||||
@@ -4,7 +4,7 @@ layout: page
|
||||
---
|
||||
|
||||
{% assign pinned = site.posts | where: "pin", "true" %}
|
||||
{% assign default = site.posts | where_exp: "item", "item.pin != true" %}
|
||||
{% assign default = site.posts | where_exp: "item", "item.pin != true and item.hidden != true" %}
|
||||
|
||||
{% assign posts = "" | split: "" %}
|
||||
|
||||
@@ -21,7 +21,6 @@ layout: page
|
||||
{% assign pinned_num = 0 %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
<!-- Get default posts -->
|
||||
|
||||
{% assign default_beg = offset | minus: pinned.size %}
|
||||
@@ -51,34 +50,34 @@ layout: page
|
||||
<div class="post-content">
|
||||
<p>
|
||||
{% include no-linenos.html content=post.content %}
|
||||
{{ content | markdownify | strip_html | truncate: 200 }}
|
||||
{{ content | markdownify | strip_html | truncate: 200 | escape }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="post-meta text-muted d-flex justify-content-between">
|
||||
<div class="post-meta text-muted d-flex">
|
||||
<div class="mr-auto">
|
||||
|
||||
<div>
|
||||
<!-- posted date -->
|
||||
<i class="far fa-calendar fa-fw"></i>
|
||||
{% include timeago.html date=post.date tooltip=true %}
|
||||
{% include datetime.html date=post.date %}
|
||||
|
||||
<!-- time to read -->
|
||||
<i class="far fa-clock fa-fw"></i>
|
||||
{% include read-time.html content=post.content %}
|
||||
|
||||
<!-- page views -->
|
||||
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
|
||||
<i class="far fa-eye fa-fw"></i>
|
||||
<span id="pv_{{-post.title-}}" class="pageviews">
|
||||
<i class="fas fa-spinner fa-spin fa-fw"></i>
|
||||
</span>
|
||||
<!-- categories -->
|
||||
{% if post.categories.size > 0 %}
|
||||
<i class="far fa-folder-open fa-fw"></i>
|
||||
<span>
|
||||
{% for category in post.categories %}
|
||||
{{ category }}
|
||||
{%- unless forloop.last -%},{%- endunless -%}
|
||||
{% endfor %}
|
||||
</span>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
{% if post.pin %}
|
||||
<div class="pin">
|
||||
<i class="fas fa-thumbtack fa-fw"></i>
|
||||
<span>{{ site.data.locales[site.lang].post.pin_prompt | default: 'Pinned' }}</span>
|
||||
<span>{{ site.data.locales[site.lang].post.pin_prompt }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -1,41 +1,63 @@
|
||||
---
|
||||
layout: default
|
||||
# The page layout
|
||||
---
|
||||
|
||||
{% include assets-origin.html %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-11 col-xl-8">
|
||||
<div id="page" class="post pb-5 pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4 mb-md-4">
|
||||
{% if page.dynamic_title %}
|
||||
|
||||
<!-- core -->
|
||||
<div id="core-wrapper" class="col-12 col-lg-11 col-xl-9 pr-xl-4">
|
||||
<div class="post pl-1 pr-1 pl-md-2 pr-md-2">
|
||||
|
||||
{% capture _content %}
|
||||
{% if layout.refactor or page.layout == 'page' %}
|
||||
{% include refactor-content.html content=content %}
|
||||
{% else %}
|
||||
{{ content }}
|
||||
{% endif %}
|
||||
{% endcapture %}
|
||||
|
||||
{% if page.layout == 'page' or page.collection == 'tabs' %}
|
||||
{% assign tab_key = page.title | downcase %}
|
||||
{% assign title = site.data.locales[site.lang].tabs[tab_key] | default: page.title %}
|
||||
<h1 class="dynamic-title">
|
||||
{% if page.collection == 'tabs' %}
|
||||
{%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%}
|
||||
{{- site.data.locales[site.lang].tabs[tab_key] | default: page.title -}}
|
||||
{% else %}
|
||||
{{- page.title -}}
|
||||
{% endif %}
|
||||
{{ title }}
|
||||
</h1>
|
||||
<div class="post-content">
|
||||
{{ content }}
|
||||
{{ _content }}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ content }}
|
||||
{{ _content }}
|
||||
{% endif %}
|
||||
</div> <!-- #page -->
|
||||
</div><!-- .col-12 -->
|
||||
|
||||
{% include panel.html %}
|
||||
</div>
|
||||
</div> <!-- #core-wrapper -->
|
||||
|
||||
<!-- panel -->
|
||||
<div id="panel-wrapper" class="col-xl-3 pl-2 text-muted">
|
||||
|
||||
<div class="access">
|
||||
{% include update-list.html %}
|
||||
{% include trending-tags.html %}
|
||||
</div>
|
||||
|
||||
{% for _include in layout.panel_includes %}
|
||||
{% assign _include_path = _include | append: '.html' %}
|
||||
{% include {{ _include_path }} %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% if site.disqus.comments and page.comments %}
|
||||
<!-- tail -->
|
||||
{% if layout.tail_includes %}
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-11 col-xl-8">
|
||||
<div class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
|
||||
|
||||
{% include disqus.html %}
|
||||
|
||||
</div> <!-- .pl-1 pr-1 -->
|
||||
</div> <!-- .col-12 -->
|
||||
</div> <!-- .row -->
|
||||
<div id="tail-wrapper" class="col-12 col-lg-11 col-xl-9 pl-3 pr-3 pr-xl-4 mt-5">
|
||||
{% for _include in layout.tail_includes %}
|
||||
{% assign _include_path = _include | append: '.html' %}
|
||||
{% include {{ _include_path }} %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user