This commit is contained in:
Bangara Raju Kottedi 2024-12-08 02:46:10 +05:30
commit a66e3fa1a3
16 changed files with 366 additions and 127 deletions

View File

@ -42,7 +42,7 @@ jobs:
- name: Setup Ruby - name: Setup Ruby
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1
with: with:
ruby-version: 3.2 ruby-version: 3.3
bundler-cache: true bundler-cache: true
- name: Build site - name: Build site
@ -53,7 +53,7 @@ jobs:
- name: Test site - name: Test site
run: | run: |
bundle exec htmlproofer _site \ bundle exec htmlproofer _site \
\-\-disable-external=true \ \-\-disable-external \
\-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/" \-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/"
- name: Upload site artifact - name: Upload site artifact

6
.gitignore vendored
View File

@ -5,6 +5,7 @@ Gemfile.lock
# Jekyll cache # Jekyll cache
.jekyll-cache .jekyll-cache
.jekyll-metadata
_site _site
# RubyGems # RubyGems
@ -16,6 +17,11 @@ package-lock.json
# IDE configurations # IDE configurations
.idea .idea
.vscode/*
!.vscode/settings.json
!.vscode/extensions.json
!.vscode/tasks.json
# Misc # Misc
_sass/vendors
assets/js/dist assets/js/dist

26
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Run Jekyll Server",
"type": "shell",
"command": "./tools/run.sh",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"detail": "Runs the Jekyll server with live reload."
},
{
"label": "Build Jekyll Site",
"type": "shell",
"command": "./tools/test.sh",
"group": {
"kind": "build"
},
"problemMatcher": [],
"detail": "Build the Jekyll site for production."
}
]
}

View File

@ -2,10 +2,10 @@
source "https://rubygems.org" source "https://rubygems.org"
gem "jekyll-theme-chirpy", "~> 6.2", ">= 6.5.5" gem "jekyll-theme-chirpy", "~> 7.2", ">= 7.2.2"
group :test do group :test do
gem "html-proofer", "~> 4.4" gem "html-proofer", "~> 5.0", group: :test
end end
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem # Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
@ -16,7 +16,7 @@ platforms :mingw, :x64_mingw, :mswin, :jruby do
end end
# Performance-booster for watching directories on Windows # Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] gem "wdm", "~> 0.2.0", :platforms => [:mingw, :x64_mingw, :mswin]
# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem # Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
# do not have a Java counterpart. # do not have a Java counterpart.

View File

@ -1,81 +1,43 @@
<div align="center"> # Chirpy Starter
# Chirpy Jekyll Theme [![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy)][gem]&nbsp;
[![GitHub license](https://img.shields.io/github/license/cotes2020/chirpy-starter.svg?color=blue)][mit]
A minimal, responsive, and feature-rich Jekyll theme for technical writing. When installing the [**Chirpy**][chirpy] theme through [RubyGems.org][gem], Jekyll can only read files in the folders
`_data`, `_layouts`, `_includes`, `_sass` and `assets`, as well as a small part of options of the `_config.yml` file
from the theme's gem. If you have ever installed this theme gem, you can use the command
`bundle info --path jekyll-theme-chirpy` to locate these files.
[![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen)][gem]&nbsp; The Jekyll team claims that this is to leave the ball in the users court, but this also results in users not being
[![CI](https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml/badge.svg?branch=master&event=push)][ci]&nbsp; able to enjoy the out-of-the-box experience when using feature-rich themes.
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/4e556876a3c54d5e8f2d2857c4f43894)][codacy]&nbsp;
[![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg)][license]&nbsp;
[![996.icu](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg)](https://996.icu)
[**Live Demo** →][demo] To fully use all the features of **Chirpy**, you need to copy the other critical files from the theme's gem to your
Jekyll site. The following is a list of targets:
[![Devices Mockup](https://chirpy-img.netlify.app/commons/devices-mockup.png)][demo] ```shell
.
├── _config.yml
├── _plugins
├── _tabs
└── index.html
```
</div> To save you time, and also in case you lose some files while copying, we extract those files/configurations of the
latest version of the **Chirpy** theme and the [CD][CD] workflow to here, so that you can start writing in minutes.
## Features ## Usage
- Dark / Light Theme Mode Check out the [theme's docs](https://github.com/cotes2020/jekyll-theme-chirpy/wiki).
- Localized UI language
- Pinned Posts on Home Page
- Hierarchical Categories
- Trending Tags
- Table of Contents
- Last Modified Date
- Syntax Highlighting
- Mathematical Expressions
- Mermaid Diagrams & Flowcharts
- Dark / Light Mode Images
- Embed Videos
- Disqus / Giscus / Utterances Comments
- Built-in Search
- Atom Feeds
- PWA
- Google Analytics / GoatCounter
- SEO & Performance Optimization
## Documentation
To learn how to use, develop, and upgrade the project, please refer to the [Wiki][wiki].
## Contributing ## Contributing
Contributions (_pull requests_, _issues_, and _discussions_) are what make the open-source community such an amazing place This repository is automatically updated with new releases from the theme repository. If you encounter any issues or want to contribute to its improvement, please visit the [theme repository][chirpy] to provide feedback.
to learn, inspire, and create. Any contributions you make are greatly appreciated.
For details, see the "[Contributing Guidelines][contribute-guide]".
## Credits
### Contributors
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]
<sub> —— Made with [contrib.rocks](https://contrib.rocks)</sub>
### Third-Party Assets
This project is built on the [Jekyll][jekyllrb] ecosystem and some [great libraries][lib], and is developed using [VS Code][vscode] as well as tools provided by [JetBrains][jetbrains] under a non-commercial open-source software license.
The avatar and favicon for the project's website are from [ClipartMAX][clipartmax].
## License ## License
This project is published under [MIT License][license]. This work is published under [MIT][mit] License.
[gem]: https://rubygems.org/gems/jekyll-theme-chirpy [gem]: https://rubygems.org/gems/jekyll-theme-chirpy
[ci]: https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml?query=event%3Apush+branch%3Amaster [chirpy]: https://github.com/cotes2020/jekyll-theme-chirpy/
[codacy]: https://app.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade [CD]: https://en.wikipedia.org/wiki/Continuous_deployment
[license]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE [mit]: https://github.com/cotes2020/chirpy-starter/blob/master/LICENSE
[jekyllrb]: https://jekyllrb.com/
[clipartmax]: https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/
[demo]: https://cotes2020.github.io/chirpy-demo/
[wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki
[contribute-guide]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/CONTRIBUTING.md
[contributors]: https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors
[lib]: https://github.com/cotes2020/chirpy-static-assets
[vscode]: https://code.visualstudio.com/
[jetbrains]: https://www.jetbrains.com/?from=jekyll-theme-chirpy

View File

@ -45,7 +45,14 @@ social:
- https://www.facebook.com/RajuKottedi435 - https://www.facebook.com/RajuKottedi435
- https://www.linkedin.com/in/bangararajuk/ - https://www.linkedin.com/in/bangararajuk/
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 # The end of `jekyll-seo-tag` settings
@ -84,12 +91,12 @@ pageviews:
# #
theme_mode: # [light | dark] theme_mode: # [light | dark]
# The CDN endpoint for images. # The CDN endpoint for media resources.
# Notice that once it is assigned, the CDN url # 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' # e.g. 'https://cdn.com'
img_cdn: cdn:
# the avatar on sidebar, support local or CORS resources # the avatar on sidebar, support local or CORS resources
avatar: /assets/img/avatar.jpg avatar: /assets/img/avatar.jpg
@ -102,7 +109,8 @@ social_preview_image: # string, local or CORS resources
toc: true toc: true
comments: comments:
active: 'remark42' # The global switch for posts comments, e.g., 'disqus'. Keep it empty means disable # Global switch for the post comment system. Keeping it empty means disabled.
provider: 'remark42' # [disqus | utterances | giscus]
# The active options are as follows: # The active options are as follows:
# remark42 settings > https://remark42.com/ # remark42 settings > https://remark42.com/
remark42: remark42:
@ -120,6 +128,7 @@ comments:
category: category:
category_id: category_id:
mapping: # optional, default to 'pathname' mapping: # optional, default to 'pathname'
strict: # optional, default to '0'
input_position: # optional, default to 'bottom' input_position: # optional, default to 'bottom'
lang: # optional, default to the value of `site.lang` lang: # optional, default to the value of `site.lang`
reactions_enabled: # optional, default to the value of `1` reactions_enabled: # optional, default to the value of `1`
@ -151,6 +160,7 @@ baseurl: "/blog"
# ------------ The following options are not recommended to be modified ------------------ # ------------ The following options are not recommended to be modified ------------------
kramdown: kramdown:
footnote_backlink: "&#8617;&#xfe0e;"
syntax_highlighter: rouge syntax_highlighter: rouge
syntax_highlighter_opts: # Rouge Options https://github.com/jneen/rouge#full-options syntax_highlighter_opts: # Rouge Options https://github.com/jneen/rouge#full-options
css_class: highlight css_class: highlight
@ -211,8 +221,9 @@ exclude:
- tools - tools
- README.md - README.md
- LICENSE - LICENSE
- purgecss.js
- rollup.config.js - rollup.config.js
- package*.json - "package*.json"
- db_scripts - db_scripts
- frontmatter.json - frontmatter.json

View File

@ -26,3 +26,15 @@
# - type: stack-overflow # - type: stack-overflow
# icon: 'fab fa-stack-overflow' # icon: 'fab fa-stack-overflow'
# url: '' # Fill with your stackoverflow homepage # url: '' # Fill with your stackoverflow homepage
#
# - type: bluesky
# icon: 'fa-brands fa-bluesky'
# url: '' # Fill with your Bluesky profile link
#
# - type: reddit
# icon: 'fa-brands fa-reddit'
# url: '' # Fill with your Reddit profile link
#
# - type: threads
# icon: 'fa-brands fa-threads'
# url: '' # Fill with your Threads profile link

View File

@ -22,7 +22,7 @@ platforms:
# #
# - type: Weibo # - type: Weibo
# icon: "fab fa-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 # - type: Mastodon
# icon: "fa-brands fa-mastodon" # icon: "fa-brands fa-mastodon"
@ -36,3 +36,15 @@ platforms:
# link: "https://fosstodon.org/" # link: "https://fosstodon.org/"
# - label: photog.social # - label: photog.social
# link: "https://photog.social/" # link: "https://photog.social/"
#
# - type: Bluesky
# icon: "fa-brands fa-bluesky"
# link: "https://bsky.app/intent/compose?text=TITLE%20URL"
#
# - type: Reddit
# icon: "fa-brands fa-square-reddit"
# link: "https://www.reddit.com/submit?url=URL&title=TITLE"
#
# - type: Threads
# icon: "fa-brands fa-square-threads"
# link: "https://www.threads.net/intent/post?text=TITLE%20URL"

View File

@ -0,0 +1,8 @@
---
title: Anatomy of a CSRF Attack
date: 2024-07-08 0:00:00 +5:30
tags:
- csrf
- security
slug: anatomy-csrf-attack
---

View File

@ -1,5 +1,5 @@
<!-- The comments switcher --> <!-- The comments switcher -->
{% if page.comments and site.comments.active %} {% if page.comments and site.comments.provider %}
{% capture path %}comments/{{ site.comments.active }}.html{% endcapture %} {% capture path %}comments/{{ site.comments.provider }}.html{% endcapture %}
{% include {{ path }} %} {% include {{ path }} %}
{% endif %} {% endif %}

View File

@ -4,7 +4,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7"> <meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7">
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e"> <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" <meta name="viewport"
content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover"> content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover">
@ -20,7 +20,7 @@
{% unless src contains '://' %} {% unless src contains '://' %}
{%- capture img_url -%} {%- 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 -%} {%- endcapture -%}
{%- capture old_url -%}{{ src | absolute_url }}{%- endcapture -%} {%- capture old_url -%}{{ src | absolute_url }}{%- endcapture -%}
@ -31,7 +31,7 @@
{% elsif site.social_preview_image %} {% elsif site.social_preview_image %}
{%- capture img_url -%} {%- 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 -%} {%- endcapture -%}
{%- capture og_image -%} {%- capture og_image -%}
@ -59,34 +59,30 @@
{% include_cached favicons.html %} {% include_cached favicons.html %}
{% if site.resources.ignore_env != jekyll.environment and site.resources.self_hosted %} <!-- Resource Hints -->
<link href="{{ site.data.origin[type].webfonts | relative_url }}" rel="stylesheet"> {% unless site.assets.self_host.enabled %}
{% for hint in site.data.origin.cors.resource_hints %}
{% else %} {% for link in hint.links %}
{% for cdn in site.data.origin[type].cdns %} <link rel="{{ link.rel }}" href="{{ hint.url }}" {{ link.opts | join: ' ' }}>
<link rel="preconnect" href="{{ cdn.url }}" {{ cdn.args }}> {% endfor %}
<link rel="dns-prefetch" href="{{ cdn.url }}" {{ cdn.args }}> {% endfor %}
{% endfor %} {% endunless %}
<link rel="stylesheet" href="{{ site.data.origin[type].webfonts | relative_url }}">
{% endif %}
<!-- GA -->
{% 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">
<link rel="preconnect" href="https://www.googletagmanager.com" crossorigin="anonymous">
<link rel="dns-prefetch" href="https://www.googletagmanager.com">
{% endif %}
<!-- Bootstrap --> <!-- Bootstrap -->
<link rel="stylesheet" href="{{ site.data.origin[type].bootstrap.css | relative_url }}"> {% unless jekyll.environment == 'production' %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
{% endunless %}
<!-- Font Awesome --> <!-- Theme style -->
<link rel="stylesheet" href="{{ '/assets/css/:THEME.css' | replace: ':THEME', site.theme | relative_url }}">
<!-- Web Font -->
<link rel="stylesheet" href="{{ site.data.origin[type].webfonts | relative_url }}">
<!-- Font Awesome Icons -->
<link rel="stylesheet" href="{{ site.data.origin[type].fontawesome.css | relative_url }}"> <link rel="stylesheet" href="{{ site.data.origin[type].fontawesome.css | relative_url }}">
<link rel="stylesheet" href="{{ '/assets/css/:THEME.css' | replace: ':THEME', site.theme | relative_url }}"> <!-- 3rd-party Dependencies -->
{% if site.toc and page.toc %} {% if site.toc and page.toc %}
<link rel="stylesheet" href="{{ site.data.origin[type].toc.css | relative_url }}"> <link rel="stylesheet" href="{{ site.data.origin[type].toc.css | relative_url }}">
@ -97,11 +93,11 @@
{% endif %} {% endif %}
{% if page.layout == 'page' or page.layout == 'post' %} {% if page.layout == 'page' or page.layout == 'post' %}
<!-- Manific Popup --> <!-- Image Popup -->
<link rel="stylesheet" href="{{ site.data.origin[type].magnific-popup.css | relative_url }}"> <link rel="stylesheet" href="{{ site.data.origin[type].glightbox.css | relative_url }}">
{% endif %} {% endif %}
<!-- JavaScript --> <!-- Scripts -->
<script> <script>
var serviceUrl = "{{site.custom-config.blog-services.service_url}}"; var serviceUrl = "{{site.custom-config.blog-services.service_url}}";
var serviceApiKey = "{{site.custom-config.blog-services.service_key}}"; var serviceApiKey = "{{site.custom-config.blog-services.service_key}}";
@ -173,9 +169,28 @@
<!-- End Microsoft Clarity --> <!-- End Microsoft Clarity -->
{% endif %} {% endif %}
{% unless site.theme_mode %} <script src="{{ '/assets/js/dist/theme.min.js' | relative_url }}"></script>
{% include mode-toggle.html %}
{% endunless %} {% include js-selector.html lang=lang %}
{% if jekyll.environment == 'production' %}
<!-- PWA -->
{% if site.pwa.enabled %}
<script
defer
src="{{ '/app.min.js' | relative_url }}?baseurl={{ site.baseurl | default: '' }}&register={{ site.pwa.cache.enabled }}"
></script>
{% endif %}
<!-- Web Analytics -->
{% for analytics in site.analytics %}
{% capture str %}{{ analytics }}{% endcapture %}
{% assign platform = str | split: '{' | first %}
{% if site.analytics[platform].id and site.analytics[platform].id != empty %}
{% include analytics/{{ platform }}.html %}
{% endif %}
{% endfor %}
{% endif %}
{% include metadata-hook.html %} {% include metadata-hook.html %}
</head> </head>

View File

@ -46,6 +46,10 @@
if(Number(views.innerText) !== NaN){ if(Number(views.innerText) !== NaN){
postDetails.views = Number(views.innerText); postDetails.views = Number(views.innerText);
} }
if(postDetails.modifiedDate === ""){
postDetails.modifiedDate = postDetails.createdDate;
}
ajax(serviceUrl + "/CreatePost", "POST", postDetails) ajax(serviceUrl + "/CreatePost", "POST", postDetails)
.then(function (result) { .then(function (result) {
if(result != "N/A"){ if(result != "N/A"){

View File

@ -12,7 +12,7 @@ layout: compress
{% endif %} {% endif %}
<!-- `site.alt_lang` can specify a language different from the UI --> <!-- `site.alt_lang` can specify a language different from the UI -->
<html lang="{{ site.alt_lang | default: site.lang }}" {{ prefer_mode }}> <html lang="{{ page.lang | default: site.lang }}" {{ prefer_mode }}>
{% include head.html %} {% include head.html %}
<body> <body>
@ -40,7 +40,7 @@ layout: compress
</main> </main>
<!-- panel --> <!-- panel -->
<aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 mb-5 text-muted"> <aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 text-muted">
<div class="access"> <div class="access">
{% include_cached update-list.html lang=lang %} {% include_cached update-list.html lang=lang %}
{% include_cached trending-tags.html lang=lang %} {% include_cached trending-tags.html lang=lang %}
@ -75,21 +75,20 @@ layout: compress
</aside> </aside>
</div> </div>
<div id="mask"></div> <div id="mask" class="d-none position-fixed w-100 h-100 z-1"></div>
{% if site.pwa.enabled %} {% if site.pwa.enabled %}
{% include_cached notification.html lang=lang %} {% include_cached notification.html lang=lang %}
{% endif %} {% endif %}
<!-- JavaScripts --> <!-- Embedded scripts -->
{% include js-selector.html %} {% for _include in layout.script_includes %}
{% assign _include_path = _include | append: '.html' %}
{% include {{ _include_path }} %}
{% endfor %}
{% if page.mermaid %} {% include_cached search-loader.html lang=lang %}
{% include mermaid.html %}
{% endif %}
{% include_cached search-loader.html %}
</body> </body>
</html> </html>

View File

@ -6,14 +6,20 @@ panel_includes:
tail_includes: tail_includes:
- related-posts - related-posts
- post-nav - post-nav
- comments script_includes:
- comment
--- ---
{% include lang.html %} {% include lang.html %}
<article class="px-1"> {% include toc-status.html %}
<article class="px-1" data-toc="{{ enable_toc }}">
<header> <header>
<h1 data-toc-skip>{{ page.title }}</h1> <h1 data-toc-skip>{{ page.title }}</h1>
{% if page.description %}
<p class="post-desc fw-light mb-4">{{ page.description }}</p>
{% endif %}
<div class="post-meta text-muted"> <div class="post-meta text-muted">
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
@ -85,15 +91,50 @@ tail_includes:
</em> </em>
</span> </span>
<!-- read time --> <div>
{% include read-time.html content=content prompt=true lang=lang %} <!-- pageviews -->
{% if site.pageviews.provider and site.analytics[site.pageviews.provider].id %}
<span>
<em id="pageviews">
<i class="fas fa-spinner fa-spin small"></i>
</em>
{{ site.data.locales[lang].post.pageview_measure }}
</span>
{% endif %}
<!-- read time -->
{% include read-time.html content=content prompt=true lang=lang %}
</div>
</div> </div>
<!-- .d-flex -->
</div> </div>
<!-- .post-meta --> <!-- .post-meta -->
{% include post-series.html %} {% include post-series.html %}
</header> </header>
{% if enable_toc %}
<div id="toc-bar" class="d-flex align-items-center justify-content-between invisible">
<span class="label text-truncate">{{ page.title }}</span>
<button type="button" class="toc-trigger btn me-1">
<i class="fa-solid fa-list-ul fa-fw"></i>
</button>
</div>
<button id="toc-solo-trigger" type="button" class="toc-trigger btn btn-outline-secondary btn-sm">
<span class="label ps-2 pe-1">{{- site.data.locales[lang].panel.toc -}}</span>
<i class="fa-solid fa-angle-right fa-fw"></i>
</button>
<dialog id="toc-popup" class="p-0">
<div class="header d-flex flex-row align-items-center justify-content-between">
<div class="label text-truncate py-2 ms-4">{{- page.title -}}</div>
<button id="toc-popup-close" type="button" class="btn mx-1 my-1 opacity-75">
<i class="fas fa-close"></i>
</button>
</div>
<div id="toc-popup-content" class="px-4 py-3 pb-4"></div>
</dialog>
{% endif %}
<div class="content"> <div class="content">
{{ content }} {{ content }}
{% if page.disable-ty != true %} {% if page.disable-ty != true %}

54
tools/run.sh Normal file
View File

@ -0,0 +1,54 @@
#!/usr/bin/env bash
#
# Run jekyll serve and then launch the site
prod=false
command="bundle exec jekyll s -l"
host="127.0.0.1"
help() {
echo "Usage:"
echo
echo " bash /path/to/run [options]"
echo
echo "Options:"
echo " -H, --host [HOST] Host to bind to."
echo " -p, --production Run Jekyll in 'production' mode."
echo " -h, --help Print this help information."
}
while (($#)); do
opt="$1"
case $opt in
-H | --host)
host="$2"
shift 2
;;
-p | --production)
prod=true
shift
;;
-h | --help)
help
exit 0
;;
*)
echo -e "> Unknown option: '$opt'\n"
help
exit 1
;;
esac
done
command="$command -H $host"
if $prod; then
command="JEKYLL_ENV=production $command"
fi
if [ -e /proc/1/cgroup ] && grep -q docker /proc/1/cgroup; then
command="$command --force_polling"
fi
echo -e "\n> $command\n"
eval "$command"

89
tools/test.sh Normal file
View File

@ -0,0 +1,89 @@
#!/usr/bin/env bash
#
# Build and test the site content
#
# Requirement: html-proofer, jekyll
#
# Usage: See help information
set -eu
SITE_DIR="_site"
_config="_config.yml"
_baseurl=""
help() {
echo "Build and test the site content"
echo
echo "Usage:"
echo
echo " bash $0 [options]"
echo
echo "Options:"
echo ' -c, --config "<config_a[,config_b[...]]>" Specify config file(s)'
echo " -h, --help Print this information."
}
read_baseurl() {
if [[ $_config == *","* ]]; then
# multiple config
IFS=","
read -ra config_array <<<"$_config"
# reverse loop the config files
for ((i = ${#config_array[@]} - 1; i >= 0; i--)); do
_tmp_baseurl="$(grep '^baseurl:' "${config_array[i]}" | sed "s/.*: *//;s/['\"]//g;s/#.*//")"
if [[ -n $_tmp_baseurl ]]; then
_baseurl="$_tmp_baseurl"
break
fi
done
else
# single config
_baseurl="$(grep '^baseurl:' "$_config" | sed "s/.*: *//;s/['\"]//g;s/#.*//")"
fi
}
main() {
# clean up
if [[ -d $SITE_DIR ]]; then
rm -rf "$SITE_DIR"
fi
read_baseurl
# build
JEKYLL_ENV=production bundle exec jekyll b \
-d "$SITE_DIR$_baseurl" -c "$_config"
# test
bundle exec htmlproofer "$SITE_DIR" \
--disable-external \
--ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/"
}
while (($#)); do
opt="$1"
case $opt in
-c | --config)
_config="$2"
shift
shift
;;
-h | --help)
help
exit 0
;;
*)
# unknown option
help
exit 1
;;
esac
done
main