diff --git a/.github/DISCUSSION_TEMPLATE/general.yml b/.github/DISCUSSION_TEMPLATE/general.yml
index 4e879f9..18d0f85 100644
--- a/.github/DISCUSSION_TEMPLATE/general.yml
+++ b/.github/DISCUSSION_TEMPLATE/general.yml
@@ -9,15 +9,6 @@ body:
[contributing guidelines](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md).
required: true
- - type: dropdown
- attributes:
- label: What is the topic?
- options:
- - Sharing tips and tricks
- - Just chatting
- validations:
- required: true
-
- type: textarea
attributes:
label: Description
diff --git a/.github/DISCUSSION_TEMPLATE/ideas.yml b/.github/DISCUSSION_TEMPLATE/ideas.yml
new file mode 100644
index 0000000..e4c987d
--- /dev/null
+++ b/.github/DISCUSSION_TEMPLATE/ideas.yml
@@ -0,0 +1,7 @@
+body:
+ - type: textarea
+ attributes:
+ label: Description
+ description: Please describe in detail what you want to share.
+ validations:
+ required: true
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index bec1046..393fa98 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -2,10 +2,6 @@ version: 2
updates:
- package-ecosystem: "bundler"
directory: "/"
- versioning-strategy: increase
- groups:
- bundler:
- dependency-type: "production"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
@@ -13,7 +9,10 @@ updates:
versioning-strategy: increase
groups:
npm:
- dependency-type: "development"
+ update-types:
+ - "major"
+ - "minor"
+ - "patch"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml
index 2e239a4..160750d 100644
--- a/.github/workflows/cd.yml
+++ b/.github/workflows/cd.yml
@@ -1,17 +1,37 @@
name: CD
+
on:
push:
- tags:
- - "v[0-9]+.[0-9]+.[0-9]+"
branches:
- - docs
+ - production
+ tags-ignore:
+ - "**"
jobs:
- launch:
+ release:
+ permissions:
+ contents: write
+ issues: write
+ pull-requests: write
runs-on: ubuntu-latest
steps:
- - run: |
- curl -X POST -H "Accept: application/vnd.github+json" \
- -H "Authorization: Bearer ${{ secrets.GH_PAT }}" \
- https://api.github.com/repos/${{ secrets.BUILDER }}/dispatches \
- -d '{"event_type":"deploy", "client_payload":{"branch": "${{ github.ref_name }}"}}'
+ - uses: actions/checkout@v4
+
+ - uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: 3.3
+ bundler-cache: true
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: latest
+
+ - run: npm install
+ - run: npx semantic-release
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GEM_HOST_API_KEY: ${{ secrets.GEM_HOST_API_KEY }}
+
+ publish:
+ needs: release
+ uses: ./.github/workflows/publish.yml
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c7b1f5a..078e4f1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,9 +1,8 @@
name: "CI"
on:
push:
- branches-ignore:
- - "production"
- - "docs"
+ branches:
+ - "master"
paths-ignore:
- ".github/**"
- "!.github/workflows/ci.yml"
@@ -12,8 +11,6 @@ on:
- "README.md"
- "LICENSE"
pull_request:
- paths:
- - "**"
jobs:
build:
@@ -21,7 +18,7 @@ jobs:
strategy:
matrix:
- ruby: ["3.0", "3.1", "3.2"]
+ ruby: ["3.1", "3.2", "3.3"]
steps:
- name: Checkout
@@ -37,6 +34,8 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v4
+ with:
+ node-version: latest
- name: Build Assets
run: npm i && npm run build
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index b09590d..06feb7f 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -2,6 +2,7 @@ name: "CodeQL"
on:
push:
+ branches: ["master"]
paths: ["_javascript/**/*.js"]
pull_request:
paths: ["_javascript/**/*.js"]
diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml
index d79814a..c9c48c3 100644
--- a/.github/workflows/commitlint.yml
+++ b/.github/workflows/commitlint.yml
@@ -6,6 +6,4 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - uses: wagoid/commitlint-github-action@v5
+ - uses: wagoid/commitlint-github-action@v6
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..20e4691
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,17 @@
+name: Publish
+
+on:
+ push:
+ branches:
+ - docs
+ workflow_call:
+
+jobs:
+ launch:
+ runs-on: ubuntu-latest
+ steps:
+ - run: |
+ curl -X POST -H "Accept: application/vnd.github+json" \
+ -H "Authorization: Bearer ${{ secrets.GH_PAT }}" \
+ https://api.github.com/repos/${{ secrets.BUILDER }}/dispatches \
+ -d '{"event_type":"deploy", "client_payload":{"branch": "${{ github.ref_name }}"}}'
diff --git a/.github/workflows/pages-deploy.yml.hook b/.github/workflows/starter/pages-deploy.yml
similarity index 96%
rename from .github/workflows/pages-deploy.yml.hook
rename to .github/workflows/starter/pages-deploy.yml
index c33b2a6..cc28f99 100644
--- a/.github/workflows/pages-deploy.yml.hook
+++ b/.github/workflows/starter/pages-deploy.yml
@@ -42,7 +42,7 @@ jobs:
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
- ruby-version: 3.2
+ ruby-version: 3.3
bundler-cache: true
- name: Build site
@@ -53,7 +53,7 @@ jobs:
- name: Test site
run: |
bundle exec htmlproofer _site \
- \-\-disable-external=true \
+ \-\-disable-external \
\-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/"
- name: Upload site artifact
diff --git a/.github/workflows/style-lint.yml b/.github/workflows/style-lint.yml
index f7aa54d..89eeaef 100644
--- a/.github/workflows/style-lint.yml
+++ b/.github/workflows/style-lint.yml
@@ -2,14 +2,10 @@ name: "Style Lint"
on:
push:
- branches-ignore:
- - "production"
- - "docs"
- paths:
- - "_sass/**/*.scss"
+ branches: ["master"]
+ paths: ["_sass/**/*.scss"]
pull_request:
- paths:
- - "_sass/**/*.scss"
+ paths: ["_sass/**/*.scss"]
jobs:
stylelint:
@@ -21,5 +17,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v4
+ with:
+ node-version: latest
- run: npm i
- run: npm test
diff --git a/.gitignore b/.gitignore
index cee9e12..d6bf509 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ Gemfile.lock
# Jekyll cache
.jekyll-cache
+.jekyll-metadata
_site
# RubyGems
@@ -16,6 +17,10 @@ package-lock.json
# IDE configurations
.idea
+.vscode
+!.vscode/settings.json
+!.vscode/extensions.json
# Misc
+_sass/dist
assets/js/dist
diff --git a/.markdownlint.json b/.markdownlint.json
new file mode 100644
index 0000000..831991e
--- /dev/null
+++ b/.markdownlint.json
@@ -0,0 +1,8 @@
+{
+ "commands-show-output": false,
+ "blanks-around-fences": false,
+ "line-length": false,
+ "no-inline-html": {
+ "allowed_elements": ["kbd", "sub"]
+ }
+}
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 6927cd1..52bd6fb 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -7,6 +7,7 @@
// Common formatter
"esbenp.prettier-vscode",
"foxundermoon.shell-format",
- "stylelint.vscode-stylelint"
+ "stylelint.vscode-stylelint",
+ "yzhang.markdown-all-in-one"
]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 4fcded4..b0e2e09 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -7,6 +7,9 @@
"files.associations": {
"*.html": "liquid"
},
+ "[markdown]": {
+ "editor.defaultFormatter": "yzhang.markdown-all-in-one"
+ },
// Formatter
"[html][liquid]": {
"editor.defaultFormatter": "Shopify.theme-check-vscode"
diff --git a/Gemfile b/Gemfile
index 043b28e..672e9e4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -5,19 +5,5 @@ source "https://rubygems.org"
gemspec
group :test do
- gem "html-proofer", "~> 4.4"
+ gem "html-proofer", "~> 5.0"
end
-
-# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
-# and associated library.
-platforms :mingw, :x64_mingw, :mswin, :jruby do
- gem "tzinfo", ">= 1", "< 3"
- gem "tzinfo-data"
-end
-
-# Performance-booster for watching directories on Windows
-gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
-
-# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
-# do not have a Java counterpart.
-gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
diff --git a/README.md b/README.md
index 0e074cf..747b8bc 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
+
+
# Chirpy Jekyll Theme
A minimal, responsive, and feature-rich Jekyll theme for technical writing.
@@ -18,7 +20,7 @@
## Features
-- Dark / Light Theme Mode
+- Dark Theme
- Localized UI language
- Pinned Posts on Home Page
- Hierarchical Categories
@@ -28,13 +30,13 @@
- Syntax Highlighting
- Mathematical Expressions
- Mermaid Diagrams & Flowcharts
-- Dark / Light Mode Images
-- Embed Videos
-- Disqus / Giscus / Utterances Comments
+- Dark Mode Images
+- Embed Media
+- Comment Systems
- Built-in Search
- Atom Feeds
- PWA
-- Google Analytics / GoatCounter
+- Web Analytics
- SEO & Performance Optimization
## Documentation
@@ -54,7 +56,7 @@ For details, see the "[Contributing Guidelines][contribute-guide]".
Thanks to [all the contributors][contributors] involved in the development of the project!
[![all-contributors](https://contrib.rocks/image?repo=cotes2020/jekyll-theme-chirpy&columns=16)][contributors]
-
—— Made with [contrib.rocks](https://contrib.rocks)
+
— Made with [contrib.rocks](https://contrib.rocks)
### Third-Party Assets
diff --git a/_config.yml b/_config.yml
index 79d451f..613b043 100644
--- a/_config.yml
+++ b/_config.yml
@@ -44,16 +44,36 @@ social:
# - https://www.facebook.com/username
# - https://www.linkedin.com/in/username
-google_site_verification: # fill in to your verification string
+# Site Verification Settings
+webmaster_verifications:
+ google: # fill in your Google verification code
+ bing: # fill in your Bing verification code
+ alexa: # fill in your Alexa verification code
+ yandex: # fill in your Yandex verification code
+ baidu: # fill in your Baidu verification code
+ facebook: # fill in your Facebook verification code
# ↑ --------------------------
# The end of `jekyll-seo-tag` settings
-google_analytics:
- id: # fill in your Google Analytics ID
+# Web Analytics Settings
+analytics:
+ google:
+ id: # fill in your Google Analytics ID
+ goatcounter:
+ id: # fill in your GoatCounter ID
+ umami:
+ id: # fill in your Umami ID
+ domain: # fill in your Umami domain
+ matomo:
+ id: # fill in your Matomo ID
+ domain: # fill in your Matomo domain
+ cloudflare:
+ id: # fill in your Cloudflare Web Analytics token
-goatcounter:
- id: # fill in your Goatcounter ID
+# Pageviews settings
+pageviews:
+ provider: # now only supports 'goatcounter'
# Prefer color scheme setting.
#
@@ -68,12 +88,12 @@ goatcounter:
#
theme_mode: # [light | dark]
-# The CDN endpoint for images.
+# The CDN endpoint for media resources.
# Notice that once it is assigned, the CDN url
-# will be added to all image (site avatar & posts' images) paths starting with '/'
+# will be added to all media resources (site avatar, posts' images, audio and video files) paths starting with '/'
#
# e.g. 'https://cdn.com'
-img_cdn: "https://chirpy-img.netlify.app"
+cdn: "https://chirpy-img.netlify.app"
# the avatar on sidebar, support local or CORS resources
avatar: "/commons/avatar.jpg"
@@ -86,8 +106,9 @@ social_preview_image: # string, local or CORS resources
toc: true
comments:
- active: # The global switch for posts comments, e.g., 'disqus'. Keep it empty means disable
- # The active options are as follows:
+ # Global switch for the post comment system. Keeping it empty means disabled.
+ provider: # [disqus | utterances | giscus]
+ # The provider 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/
@@ -101,6 +122,7 @@ comments:
category:
category_id:
mapping: # optional, default to 'pathname'
+ strict: # optional, default to '0'
input_position: # optional, default to 'bottom'
lang: # optional, default to the value of `site.lang`
reactions_enabled: # optional, default to the value of `1`
@@ -131,6 +153,7 @@ baseurl: ""
# ------------ The following options are not recommended to be modified ------------------
kramdown:
+ footnote_backlink: "↩︎"
syntax_highlighter: rouge
syntax_highlighter_opts: # Rouge Options › https://github.com/jneen/rouge#full-options
css_class: highlight
@@ -191,7 +214,7 @@ exclude:
- tools
- README.md
- LICENSE
- - rollup.config.js
+ - "*.config.js"
- package*.json
jekyll-archives:
diff --git a/_data/media.yml b/_data/media.yml
new file mode 100644
index 0000000..9cd69b4
--- /dev/null
+++ b/_data/media.yml
@@ -0,0 +1,18 @@
+- extension: mp3
+ mime_type: mpeg
+- extension: mov
+ mime_type: quicktime
+- extension: avi
+ mime_type: x-msvideo
+- extension: mkv
+ mime_type: x-matroska
+- extension: ogv
+ mime_type: ogg
+- extension: weba
+ mime_type: webm
+- extension: 3gp
+ mime_type: 3gpp
+- extension: 3g2
+ mime_type: 3gpp2
+- extension: mid
+ mime_type: midi
diff --git a/_data/origin/basic.yml b/_data/origin/basic.yml
index ed99ea8..9027e6e 100644
--- a/_data/origin/basic.yml
+++ b/_data/origin/basic.yml
@@ -4,13 +4,6 @@ webfonts: /assets/lib/fonts/main.css
# Libraries
-jquery:
- js: /assets/lib/jquery/jquery.min.js
-
-bootstrap:
- css: /assets/lib/bootstrap/bootstrap.min.css
- js: /assets/lib/bootstrap/bootstrap.bundle.min.js
-
toc:
css: /assets/lib/tocbot/tocbot.min.css
js: /assets/lib/tocbot/tocbot.min.js
@@ -31,9 +24,9 @@ dayjs:
relativeTime: /assets/lib/dayjs/plugin/relativeTime.min.js
localizedFormat: /assets/lib/dayjs/plugin/localizedFormat.min.js
-magnific-popup:
- css: /assets/lib/magnific-popup/magnific-popup.css
- js: /assets/lib/magnific-popup/jquery.magnific-popup.min.js
+glightbox:
+ css: /assets/lib/glightbox/glightbox.min.css
+ js: /assets/lib/glightbox/glightbox.min.js
lazy-polyfill:
css: /assets/lib/loading-attribute-polyfill/loading-attribute-polyfill.min.css
diff --git a/_data/origin/cors.yml b/_data/origin/cors.yml
index b6c8674..abedb6c 100644
--- a/_data/origin/cors.yml
+++ b/_data/origin/cors.yml
@@ -1,29 +1,24 @@
-# CDNs
-
-cdns:
- # Google Fonts
+# Resource Hints
+resource_hints:
- url: https://fonts.googleapis.com
+ links:
+ - rel: preconnect
+ - rel: dns-prefetch
- url: https://fonts.gstatic.com
- args: crossorigin
- - url: https://fonts.googleapis.com
- # jsDelivr CDN
+ links:
+ - rel: preconnect
+ opts: [crossorigin]
+ - rel: dns-prefetch
- url: https://cdn.jsdelivr.net
- # polyfill.io for math (cdnjs.cloudflare.com/polyfill)
- - url: https://cdnjs.cloudflare.com
+ links:
+ - rel: preconnect
+ - rel: dns-prefetch
-# fonts
-
-webfonts: https://fonts.googleapis.com/css2?family=Lato&family=Source+Sans+Pro:wght@400;600;700;900&display=swap
+# Web Fonts
+webfonts: https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Source+Sans+Pro:wght@400;600;700;900&display=swap
# Libraries
-jquery:
- js: https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js
-
-bootstrap:
- css: https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css
- js: https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js
-
toc:
css: https://cdn.jsdelivr.net/npm/tocbot@4.25.0/dist/tocbot.min.css
js: https://cdn.jsdelivr.net/npm/tocbot@4.25.0/dist/tocbot.min.js
@@ -44,9 +39,9 @@ dayjs:
relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/relativeTime.min.js
localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/localizedFormat.min.js
-magnific-popup:
- css: https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/magnific-popup.min.css
- js: https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/jquery.magnific-popup.min.js
+glightbox:
+ css: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/css/glightbox.min.css
+ js: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/js/glightbox.min.js
lazy-polyfill:
css: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.min.css
diff --git a/_data/share.yml b/_data/share.yml
index d572e6d..b1d077d 100644
--- a/_data/share.yml
+++ b/_data/share.yml
@@ -22,7 +22,7 @@ platforms:
#
# - type: Weibo
# icon: "fab fa-weibo"
- # link: "http://service.weibo.com/share/share.php?title=TITLE&url=URL"
+ # link: "https://service.weibo.com/share/share.php?title=TITLE&url=URL"
#
# - type: Mastodon
# icon: "fa-brands fa-mastodon"
diff --git a/_includes/analytics/cloudflare.html b/_includes/analytics/cloudflare.html
new file mode 100644
index 0000000..1eeb1a9
--- /dev/null
+++ b/_includes/analytics/cloudflare.html
@@ -0,0 +1,7 @@
+
+
+
diff --git a/_includes/analytics/goatcounter.html b/_includes/analytics/goatcounter.html
new file mode 100644
index 0000000..3867fdb
--- /dev/null
+++ b/_includes/analytics/goatcounter.html
@@ -0,0 +1,6 @@
+
+
diff --git a/_includes/analytics/google.html b/_includes/analytics/google.html
new file mode 100644
index 0000000..d0aac65
--- /dev/null
+++ b/_includes/analytics/google.html
@@ -0,0 +1,13 @@
+
+
+
diff --git a/_includes/analytics/matomo.html b/_includes/analytics/matomo.html
new file mode 100644
index 0000000..72b2c46
--- /dev/null
+++ b/_includes/analytics/matomo.html
@@ -0,0 +1,14 @@
+
+
+
diff --git a/_includes/analytics/umami.html b/_includes/analytics/umami.html
new file mode 100644
index 0000000..bfcb1d0
--- /dev/null
+++ b/_includes/analytics/umami.html
@@ -0,0 +1,6 @@
+
+
diff --git a/_includes/comments.html b/_includes/comments.html
index 39e521f..fef135f 100644
--- a/_includes/comments.html
+++ b/_includes/comments.html
@@ -1,5 +1,5 @@
-
-{% if page.comments and site.comments.active %}
- {% capture path %}comments/{{ site.comments.active }}.html{% endcapture %}
+
+{% if page.comments and site.comments.provider %}
+ {% capture path %}comments/{{ site.comments.provider }}.html{% endcapture %}
{% include {{ path }} %}
{% endif %}
diff --git a/_includes/comments/disqus.html b/_includes/comments/disqus.html
index e59ed37..2b889a4 100644
--- a/_includes/comments/disqus.html
+++ b/_includes/comments/disqus.html
@@ -10,7 +10,7 @@
this.page.identifier = '{{ page.url }}';
};
- /* Lazy loading */
+ {%- comment -%} Lazy loading {%- endcomment -%}
var disqus_observer = new IntersectionObserver(
function (entries) {
if (entries[0].isIntersecting) {
@@ -28,12 +28,12 @@
{ threshold: [0] }
);
- disqus_observer.observe(document.querySelector('#disqus_thread'));
+ disqus_observer.observe(document.getElementById('disqus_thread'));
- /* Auto switch theme */
+ {%- comment -%} Auto switch theme {%- endcomment -%}
function reloadDisqus() {
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
- /* Disqus hasn't been loaded */
+ {%- comment -%} Disqus hasn't been loaded {%- endcomment -%}
if (typeof DISQUS === 'undefined') {
return;
}
@@ -44,7 +44,7 @@
}
}
- if (document.querySelector('.mode-toggle')) {
+ if (document.getElementById('mode-toggle')) {
window.addEventListener('message', reloadDisqus);
}
diff --git a/_includes/comments/giscus.html b/_includes/comments/giscus.html
index 8f04246..c8d48e6 100644
--- a/_includes/comments/giscus.html
+++ b/_includes/comments/giscus.html
@@ -2,7 +2,6 @@
-
diff --git a/_includes/google-analytics.html b/_includes/google-analytics.html
deleted file mode 100644
index e5e5119..0000000
--- a/_includes/google-analytics.html
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
diff --git a/_includes/head.html b/_includes/head.html
index c9187a3..fd260c0 100644
--- a/_includes/head.html
+++ b/_includes/head.html
@@ -20,7 +20,7 @@
{% unless src contains '://' %}
{%- capture img_url -%}
- {% include img-url.html src=src img_path=page.img_path absolute=true %}
+ {% include media-url.html src=src subpath=page.media_subpath absolute=true %}
{%- endcapture -%}
{%- capture old_url -%}{{ src | absolute_url }}{%- endcapture -%}
@@ -31,7 +31,7 @@
{% elsif site.social_preview_image %}
{%- capture img_url -%}
- {% include img-url.html src=site.social_preview_image absolute=true %}
+ {% include media-url.html src=site.social_preview_image absolute=true %}
{%- endcapture -%}
{%- capture og_image -%}
@@ -59,34 +59,30 @@
{% include_cached favicons.html %}
- {% if site.resources.ignore_env != jekyll.environment and site.resources.self_hosted %}
-
-
- {% else %}
- {% for cdn in site.data.origin[type].cdns %}
-
-
+
+ {% unless site.assets.self_host.enabled %}
+ {% for hint in site.data.origin.cors.resource_hints %}
+ {% for link in hint.links %}
+
+ {% endfor %}
{% endfor %}
-
-
- {% endif %}
-
-
- {% if jekyll.environment == 'production' and site.google_analytics.id != empty and site.google_analytics.id %}
-
-
-
-
-
- {% endif %}
+ {% endunless %}
-
+ {% unless jekyll.environment == 'production' %}
+
+ {% endunless %}
-
+
+
+
+
+
+
+
-
+
{% if site.toc and page.toc %}
@@ -97,8 +93,8 @@
{% endif %}
{% if page.layout == 'page' or page.layout == 'post' %}
-
-
+
+
{% endif %}
diff --git a/_includes/js-selector.html b/_includes/js-selector.html
index 1fd408a..b229b70 100644
--- a/_includes/js-selector.html
+++ b/_includes/js-selector.html
@@ -2,12 +2,7 @@
-{% assign urls = site.data.origin[type].jquery.js
- | append: ','
- | append: site.data.origin[type].bootstrap.js
- | append: ','
- | append: site.data.origin[type].search.js
-%}
+{% assign urls = site.data.origin[type].search.js %}
@@ -20,7 +15,7 @@
{% assign urls = urls
| append: ','
- | append: site.data.origin[type]['magnific-popup'].js
+ | append: site.data.origin[type].glightbox.js
| append: ','
| append: site.data.origin[type].clipboard.js
%}
@@ -33,7 +28,7 @@
or page.layout == 'category'
or page.layout == 'tag'
%}
- {% assign locale = site.lang | split: '-' | first %}
+ {% assign locale = include.lang | split: '-' | first %}
{% assign urls = urls
| append: ','
@@ -68,46 +63,45 @@
{% endcase %}
{% capture script %}{{ js_dist }}{{ js }}.min.js{% endcapture %}
-
+
{% if page.math %}
-
+
{% endif %}
+
+{% if page.layout == 'post' %}
+ {% assign provider = site.pageviews.provider %}
+
+ {% if provider and provider != empty %}
+ {% case provider %}
+ {% when 'goatcounter' %}
+ {% if site.analytics[provider].id != empty and site.analytics[provider].id %}
+ {% include pageviews/{{ provider }}.html %}
+ {% endif %}
+ {% endcase %}
+ {% endif %}
+{% endif %}
+
+{% if page.mermaid %}
+ {% include mermaid.html %}
+{% endif %}
+
{% if jekyll.environment == 'production' %}
{% if site.pwa.enabled %}
{% endif %}
-
- {% if site.google_analytics.id != empty and site.google_analytics.id %}
- {% include google-analytics.html %}
- {% endif %}
-
-
- {% if site.goatcounter.id != empty and site.goatcounter.id %}
- {% include goatcounter.html %}
- {% endif %}
+
+ {% for analytics in site.analytics %}
+ {% capture str %}{{ analytics }}{% endcapture %}
+ {% assign type = str | split: '{' | first %}
+ {% if site.analytics[type].id and site.analytics[type].id != empty %}
+ {% include analytics/{{ type }}.html %}
+ {% endif %}
+ {% endfor %}
{% endif %}
diff --git a/_includes/lang.html b/_includes/lang.html
index 19558a0..34b50df 100644
--- a/_includes/lang.html
+++ b/_includes/lang.html
@@ -1,7 +1,9 @@
{% comment %}
Detect appearance language and return it through variable "lang"
{% endcomment %}
-{% if site.data.locales[site.lang] %}
+{% if site.data.locales[page.lang] %}
+ {% assign lang = page.lang %}
+{% elsif site.data.locales[site.lang] %}
{% assign lang = site.lang %}
{% else %}
{% assign lang = 'en' %}
diff --git a/_includes/img-url.html b/_includes/media-url.html
similarity index 59%
rename from _includes/img-url.html
rename to _includes/media-url.html
index bb4758c..ea41075 100644
--- a/_includes/img-url.html
+++ b/_includes/media-url.html
@@ -1,25 +1,25 @@
{%- comment -%}
- Generate image final URL based on `site.img_cdn`, `page.img_path`
+ Generate media resource final URL based on `site.cdn`, `page.media_subpath`
Arguments:
- src - required, basic image path
- img_path - optional, relative path of image
+ src - required, basic media resources path
+ subpath - optional, relative path of media resources
absolute - optional, boolean, if true, generate absolute URL
Return:
- image URL
+ media resources URL
{%- endcomment -%}
{% assign url = include.src %}
{%- if url -%}
{% unless url contains ':' %}
- {%- comment -%} Add page image path prefix {%- endcomment -%}
- {% assign url = include.img_path | default: '' | append: '/' | append: url %}
+ {%- comment -%} Add media resources subpath prefix {%- endcomment -%}
+ {% assign url = include.subpath | default: '' | append: '/' | append: url %}
{%- comment -%} Prepend CND URL {%- endcomment -%}
- {% if site.img_cdn %}
- {% assign url = site.img_cdn | append: '/' | append: url %}
+ {% if site.cdn %}
+ {% assign url = site.cdn | append: '/' | append: url %}
{% endif %}
{% assign url = url | replace: '///', '/' | replace: '//', '/' | replace: ':/', '://' %}
diff --git a/_includes/mermaid.html b/_includes/mermaid.html
index 967cfb4..a3a83ed 100644
--- a/_includes/mermaid.html
+++ b/_includes/mermaid.html
@@ -1,29 +1,33 @@
diff --git a/_includes/mode-toggle.html b/_includes/mode-toggle.html
index a347750..113ec37 100644
--- a/_includes/mode-toggle.html
+++ b/_includes/mode-toggle.html
@@ -19,45 +19,32 @@
}
constructor() {
- if (this.hasMode) {
- if (this.isDarkMode) {
- if (!this.isSysDarkPrefer) {
- this.setDark();
- }
- } else {
- if (this.isSysDarkPrefer) {
- this.setLight();
- }
- }
- }
-
let self = this;
- /* always follow the system prefers */
+ {%- comment -%} always follow the system prefers {%- endcomment -%}
this.sysDarkPrefers.addEventListener('change', () => {
if (self.hasMode) {
- if (self.isDarkMode) {
- if (!self.isSysDarkPrefer) {
- self.setDark();
- }
- } else {
- if (self.isSysDarkPrefer) {
- self.setLight();
- }
- }
-
self.clearMode();
}
-
self.notify();
});
- } /* constructor() */
+
+ if (!this.hasMode) {
+ return;
+ }
+
+ if (this.isDarkMode) {
+ this.setDark();
+ } else {
+ this.setLight();
+ }
+ }
get sysDarkPrefers() {
return window.matchMedia('(prefers-color-scheme: dark)');
}
- get isSysDarkPrefer() {
+ get isPreferDark() {
return this.sysDarkPrefers.matches;
}
@@ -65,10 +52,6 @@
return this.mode === ModeToggle.DARK_MODE;
}
- get isLightMode() {
- return this.mode === ModeToggle.LIGHT_MODE;
- }
-
get hasMode() {
return this.mode != null;
}
@@ -77,12 +60,12 @@
return sessionStorage.getItem(ModeToggle.MODE_KEY);
}
- /* get the current mode on screen */
+ {%- comment -%} get the current mode on screen {%- endcomment -%}
get modeStatus() {
- if (this.isDarkMode || (!this.hasMode && this.isSysDarkPrefer)) {
- return ModeToggle.DARK_MODE;
+ if (this.hasMode) {
+ return this.mode;
} else {
- return ModeToggle.LIGHT_MODE;
+ return this.isPreferDark ? ModeToggle.DARK_MODE : ModeToggle.LIGHT_MODE;
}
}
@@ -101,7 +84,9 @@
sessionStorage.removeItem(ModeToggle.MODE_KEY);
}
- /* Notify another plugins that the theme mode has changed */
+ {%- comment -%}
+ Notify another plugins that the theme mode has changed
+ {%- endcomment -%}
notify() {
window.postMessage(
{
@@ -114,21 +99,9 @@
flipMode() {
if (this.hasMode) {
- if (this.isSysDarkPrefer) {
- if (this.isLightMode) {
- this.clearMode();
- } else {
- this.setLight();
- }
- } else {
- if (this.isDarkMode) {
- this.clearMode();
- } else {
- this.setDark();
- }
- }
+ this.clearMode();
} else {
- if (this.isSysDarkPrefer) {
+ if (this.isPreferDark) {
this.setLight();
} else {
this.setDark();
@@ -136,8 +109,8 @@
}
this.notify();
- } /* flipMode() */
- } /* ModeToggle */
+ }
+ }
const modeToggle = new ModeToggle();
diff --git a/_includes/pageviews/goatcounter.html b/_includes/pageviews/goatcounter.html
new file mode 100644
index 0000000..af536db
--- /dev/null
+++ b/_includes/pageviews/goatcounter.html
@@ -0,0 +1,18 @@
+
+
diff --git a/_includes/post-description.html b/_includes/post-description.html
new file mode 100644
index 0000000..6c40036
--- /dev/null
+++ b/_includes/post-description.html
@@ -0,0 +1,16 @@
+{%- comment -%}
+ Get post description or generate it from the post content.
+{%- endcomment -%}
+
+{%- assign max_length = include.max_length | default: 200 -%}
+
+{%- capture description -%}
+{%- if post.description -%}
+ {{- post.description -}}
+{%- else -%}
+ {%- include no-linenos.html content=post.content -%}
+ {{- content | markdownify | strip_html -}}
+{%- endif -%}
+{%- endcapture -%}
+
+{{- description | strip | truncate: max_length | escape -}}
diff --git a/_includes/refactor-content.html b/_includes/refactor-content.html
index e4abcbc..8d298cd 100644
--- a/_includes/refactor-content.html
+++ b/_includes/refactor-content.html
@@ -97,7 +97,7 @@
{% assign _lazyload = true %}
{%- capture _img_url -%}
- {% include img-url.html src=_src img_path=page.img_path %}
+ {% include media-url.html src=_src subpath=page.media_subpath %}
{%- endcapture -%}
{% assign _path_prefix = _img_url | remove: _src %}
diff --git a/_includes/related-posts.html b/_includes/related-posts.html
index 1ba2f32..37a295b 100644
--- a/_includes/related-posts.html
+++ b/_includes/related-posts.html
@@ -21,6 +21,7 @@
{% assign match_posts = match_posts | push: site.tags[tag] | uniq %}
{% endfor %}
+{% assign match_posts = match_posts | reverse %}
{% assign last_index = match_posts.size | minus: 1 %}
{% assign score_list = '' | split: '' %}
@@ -81,10 +82,7 @@
{% include datetime.html date=post.date lang=include.lang %}
{{ post.title }}
-
- {% include no-linenos.html content=post.content %}
- {{ content | markdownify | strip_html | truncate: 200 | escape }}
-
+
{% include post-description.html %}
diff --git a/_includes/search-loader.html b/_includes/search-loader.html
index be3ca8a..2582580 100644
--- a/_includes/search-loader.html
+++ b/_includes/search-loader.html
@@ -19,7 +19,7 @@
{% capture not_found %}