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 %}

{{ site.data.locales[include.lang].search.no_results }}

{% endcapture %}