1
0
mirror of https://github.com/cotes2020/jekyll-theme-chirpy.git synced 2025-12-18 21:53:26 +00:00

Compare commits

...

245 Commits

Author SHA1 Message Date
Cotes Chung
d098ddb5f0 Merge branch 'hotfix/5.0.1' 2022-01-05 03:14:57 +08:00
Cotes Chung
209b175f25 Merge branch 'feature/docs' 2022-01-05 00:53:49 +08:00
Cotes Chung
aeb2d57b60 Bump version to 5.0.0 2022-01-03 00:44:23 +08:00
Cotes Chung
2406ce1dc8 Merge branch 'feature/docs' 2022-01-03 00:42:16 +08:00
Cotes Chung
bec9246823 Fix preview image brightness in dark mode 2022-01-03 00:32:57 +08:00
Cotes Chung
adaefc02e9 Update docs 2022-01-03 00:17:30 +08:00
Cotes Chung
ee7266ff0d Update mockup image 2022-01-03 00:17:30 +08:00
Cotes Chung
cad62feb91 Beautify the style of <kbd> (resolve #471) 2022-01-02 16:28:42 +08:00
Cotes Chung
b85cb39388 Replace the demo website URL with a permalink 2022-01-02 16:17:32 +08:00
Cotes Chung
4360e2938c Avoid Disqus jitter 2021-12-31 20:49:00 +08:00
Cotes Chung
ecf31ff308 Fix the code style of SASS 2021-12-31 00:33:04 +08:00
Cotes Chung
37344ef0df Merge branch 'feature/post-img-path' 2021-12-31 00:09:58 +08:00
Cotes Chung
9e2a4fc8c9 Merge branch 'feature/simplify-html-struct' 2021-12-31 00:09:53 +08:00
Cotes Chung
fc71289dc8 Bypass Jekyll build on the gh-pages branch 2021-12-31 00:09:13 +08:00
Cotes Chung
c8fd0d728d Clean up the JS log when the post is scrolled(mobile views) 2021-12-31 00:09:09 +08:00
Cotes Chung
ef2aa525d5 Add intro for img_path 2021-12-31 00:00:28 +08:00
Cotes Chung
1fe0b2958b Add new variable img_path for posts 2021-12-31 00:00:28 +08:00
Cotes Chung
e466a643d5 Merge branch 'feature/multi-comments' 2021-12-30 23:08:09 +08:00
iwasaki501
f7ec9cd24a Bug Fix: Link in a heading is rendered as an anchor and becomes invisible unless it is hovered. (#469)
`<a>` tags in headings are set to apply the style of `%anchor` in `module.scss` and `common.scss`.
Therefore, if I put a link in a heading, the link will have the same style as the anchor,
which means that the font size becomes smaller and the link will not be displayed unless I hover the mouse over it.
My suggestion is to set an `anchor` class for the `<a>` tag of the anchor and apply style settings to the `anchor` class, not to the `a` tag.
2021-12-30 15:57:02 +08:00
Cotes Chung
3342abc9e6 Refactor the page layout 2021-12-30 00:38:32 +08:00
mirusu400
d47ec035d3 Add Korean locales (#467)
Add Korean translation
2021-12-26 14:53:32 +08:00
Cotes Chung
a403ffee42 Reduce style class for page layout 2021-12-13 21:09:32 +08:00
Cotes Chung
d315bf57e7 Integrate utterances comments 2021-12-13 04:40:05 +08:00
Cotes Chung
75176522e3 Prepare for multiple comment systems 2021-12-13 03:34:46 +08:00
Cotes Chung
ebb3dc940c Merge branch 'feature/refactor-theme-mode-switch' 2021-12-13 03:33:32 +08:00
Cotes Chung
c02c9c6a04 Decouple theme-mode toggle & mermaid 2021-12-13 03:33:01 +08:00
Cotes Chung
3a4316b29b Merge branch 'feature/fix-img-param-abbr' 2021-12-13 02:39:44 +08:00
Cotes Chung
f4b2dfe8b4 Fix the conversion of image width/height abbreviation 2021-12-12 00:38:49 +08:00
Cotes Chung
09e8eb4274 Make the preview image full screen width on mobile 2021-12-10 21:54:24 +08:00
Cotes Chung
5ca0966c41 Merge branch 'feature/improve-heading-ux' 2021-12-10 21:54:11 +08:00
Cotes Chung
d919f833f1 Show heading anchor on touch devices 2021-12-10 00:28:50 +08:00
Cotes Chung
df81012e28 Always close the top bar when smooth scrolling 2021-12-10 00:28:50 +08:00
Cotes Chung
09742d40dd Prevent the anchor of the heading from being awakened early 2021-12-09 18:52:02 +08:00
Cotes Chung
259d0deabc Merge branch 'feature/improve-audits' 2021-12-07 23:21:47 +08:00
Cotes Chung
cf6c8e9b3a Improve accessibility of panel heading elements 2021-12-07 23:09:00 +08:00
Cotes Chung
c64e587335 Improve SEO & accessibility on mode toggle element 2021-12-07 23:09:00 +08:00
Cotes Chung
415f11ecb8 Escape characters of post list (homepage and related posts)
To pass the html-proofer test
2021-12-07 16:40:19 +08:00
Cotes Chung
5dc830d11e Merge branch 'feature/add-heading-anchors' 2021-12-07 16:28:19 +08:00
Cotes Chung
7579644e8d Make the anchor scroll position more precise 2021-12-07 16:26:26 +08:00
Cotes Chung
4cff83268b Reduce refactor scope 2021-12-07 16:26:26 +08:00
Cotes Chung
1487ae5284 Add style for heading anchor 2021-12-07 16:26:26 +08:00
Cotes Chung
697c584b48 Merge branch 'feature/fix-pannel-toc' 2021-12-07 15:00:07 +08:00
Cotes Chung
089a19bc9e Merge branch 'feature/support-image-parameter-abbreviation' 2021-12-07 14:59:11 +08:00
Cotes Chung
007d242e87 Fix ToC incorrectly display the contents of the panel
Bug introduced in the commit `b518c9d`
2021-12-07 14:53:48 +08:00
Cotes Chung
6447ffaf59 Add new feature intro to docs 2021-12-07 01:04:13 +08:00
Cotes Chung
790cf30376 Add abbreviation support for image width/height 2021-12-07 01:04:13 +08:00
Cotes Chung
45adf4aac2 Create anchor for headings 2021-12-06 03:04:50 +08:00
Cotes Chung
b1377ac694 Improve heading font-size & layout 2021-12-05 23:44:04 +08:00
Cotes Chung
cf8dae9454 Merge branch 'feature/improve-meta-display'
# Conflicts:
#	_sass/addon/commons.scss
2021-12-05 17:46:14 +08:00
Cotes Chung
9f5e579596 Merge branch 'feature/use-default-scrollbar' 2021-12-05 16:42:43 +08:00
Cotes Chung
99e468cae5 Merge branch 'feature/improve-post-design' 2021-12-05 16:42:38 +08:00
Cotes Chung
4fde37e879 Merge branch 'feature/switch-funding' 2021-12-05 16:35:00 +08:00
Cotes Chung
19debc4add Switch donation method from BMC to Kofi 2021-12-05 16:29:46 +08:00
Cotes Chung
afcf0bde22 Refactor footer style 2021-12-05 04:42:53 +08:00
Cotes Chung
36f55f091d Add content to the tutorial 2021-12-05 04:42:53 +08:00
Cotes Chung
e2003f2b03 Add a link to the author of the post 2021-12-05 04:42:53 +08:00
Cotes Chung
563e8085e8 Redesign the post meta layout
- posted date
- updated date
- read time
- license statement of post bottom
- also refactor the `timeago.js`
2021-12-05 04:42:53 +08:00
Cotes Chung
902546cf4d Remove unused style for mode-toggle 2021-12-03 21:23:37 +08:00
Cotes Chung
e06d237eae Use the default scroll bar
And make the Chrome scroll bar on Windows support dark mode
2021-12-03 21:23:37 +08:00
Cotes Chung
6220d09ffb Replace the pageviews with categories on home page 2021-12-03 21:03:31 +08:00
Cotes Chung
3c91dc1f6f Move the preview image of the post to the top 2021-12-03 16:36:40 +08:00
Cotes Chung
6a65f3a7f7 New design for code snippet header 2021-12-03 16:34:26 +08:00
Cotes Chung
57feaa660e Upgrade uglify-js to v3.14.3 2021-12-02 23:33:39 +08:00
Cotes Chung
db9cfc270b Fix code style issue 2021-12-02 21:32:26 +08:00
Cotes Chung
3caacbee61 Improve mobile title display
Also fixed the 404 page title on mobile screens
2021-12-02 21:18:18 +08:00
Cotes Chung
b518c9d3bc Merge branch 'feature/refactor-layouts' 2021-12-02 05:54:56 +08:00
Cotes Chung
1c758cf4a2 Update related styles 2021-12-02 05:54:43 +08:00
Cotes Chung
df3a703988 Refactor HTML structure 2021-12-02 05:54:43 +08:00
Cotes Chung
12407bbfc0 Merge branch 'feature/hide-mouse-cursor' 2021-12-02 05:53:13 +08:00
Cotes Chung
55fce7574c Refactor theme mode toggle
- Improve mode switching JS execution priority
- Drop deprecated Web API
2021-12-02 05:51:30 +08:00
Cotes Chung
833b6c9d5c Hide the cursor of icons, images, and code snippets
Found on Windows with mouse
2021-12-02 05:51:30 +08:00
Cotes Chung
a34b77969f Simplify the style of <a> 2021-12-02 05:51:30 +08:00
Bhavy Khatri
707466b1df Accessibility Bug Fix: Tab focus doesn't reach Dark mode toggle button (#453) 2021-12-01 00:23:22 +08:00
Cotes Chung
602e98448d Merge branch 'hotfix/4.3.4' 2021-11-29 21:05:44 +08:00
Cotes Chung
0bf7a8f1d9 Bump version to 4.3.4 2021-11-29 21:03:53 +08:00
Cotes Chung
a7361717a6 Exclude NPM lock-file from output 2021-11-29 21:03:53 +08:00
Cotes Chung
e880448ba5 Fix code-language conversion (json, plaintext) 2021-11-29 21:03:53 +08:00
Cotes Chung
c28b6ce7d1 Fix markdown indentation 2021-11-29 21:03:53 +08:00
Cotes Chung
b7cc22983f Prevent multiple reserse-footnote from overlapping (fix #439) 2021-10-31 22:56:22 +08:00
Cotes Chung
a1551cd740 Merge branch 'feature/code-style' into develop 2021-10-26 04:31:31 +08:00
Cotes Chung
35c4d480ed Update Codacy badge of README 2021-10-26 04:29:16 +08:00
Cotes Chung
b5c26fed08 Fix SCSS code style 2021-10-26 04:29:16 +08:00
Cotes Chung
2dc2175723 Fix JS code style 2021-10-26 04:29:16 +08:00
Cotes Chung
2f79b8d408 Fix code style for Markdown 2021-10-26 04:29:16 +08:00
Cotes
cbe6c3fb7b Skip the Jekyll build on the source code 2021-10-23 03:34:19 +08:00
Cotes Chung
bb1188a01a Merge branch 'hotfix/4.3.3' 2021-10-20 06:29:03 +08:00
Cotes Chung
406ed520cb Bump version to 4.3.3 2021-10-20 06:28:49 +08:00
Cotes Chung
1d7a134dd5 Fix exclude list 2021-10-20 06:17:53 +08:00
Cotes Chung
421db9dc92 Merge branch 'hotfix/4.3.2' 2021-10-15 00:49:57 +08:00
Cotes Chung
a5b8e7862b Bump version to 4.3.2 2021-10-15 00:49:13 +08:00
Cotes Chung
30d3249782 Remove the host of the search result URLs 2021-10-15 00:49:13 +08:00
Cotes Chung
fa15aebbca Fix the failure of the init-tool with the —no-gh option (resolve #429) 2021-10-15 00:49:13 +08:00
Cotes Chung
565ad9229c Remove the value of img_cdn and avatar from the gem package 2021-10-15 00:49:13 +08:00
Cotes Chung
3d6304efd8 Build on the release branches to reuse the travis cache 2021-10-15 00:49:13 +08:00
Cotes Chung
80fd684577 Improve the issue templates 2021-10-04 18:04:15 +08:00
Cotes Chung
80980465d7 Correct grammar and spelling in docs & issue templates
Also improve the Markdown code style
2021-10-04 17:53:07 +08:00
Cotes Chung
2858a082a3 Merge branch 'hotfix/4.3.1' 2021-10-01 18:49:10 +08:00
Cotes Chung
9b0b7d7772 Bump version to 4.3.1 2021-10-01 18:48:42 +08:00
Cotes Chung
952b1f493b Fix contents in tutorials
- Correct the aspect ratio of the mockup image
- Delete code snippet space in docs
2021-10-01 18:39:02 +08:00
Cotes Chung
a887f1d57d Prevent the site test from failing when the avatar is not assigned (close #418)
Some rookies like to do this :(
2021-10-01 18:39:02 +08:00
Cotes Chung
945e8d1953 Bump version to 4.3.0 2021-09-30 02:32:57 +08:00
Cotes Chung
a400dc9501 Specify the version of the images in the CDN 2021-09-30 02:23:34 +08:00
Cotes Chung
6a4169fc03 Make the init tool compatible with BSD 2021-09-30 02:17:24 +08:00
Cotes Chung
95b4b453e6 Merge branch 'feature/docs' into develop 2021-09-30 00:17:24 +08:00
Cotes Chung
de14c00570 Improve README header 2021-09-29 22:36:47 +08:00
Cotes Chung
f4d4065b1c Update the tutorials 2021-09-29 22:36:47 +08:00
Cotes Chung
52f854a2da Update the comment of _config.yml
Reduce the probability of users using `baseurl` incorrectly
2021-09-29 22:36:47 +08:00
Cotes Chung
38f20e8119 Update issue template 2021-09-29 22:36:47 +08:00
Cotes Chung
1728d697e6 Merge branch 'feature/enhance-script-tools' into develop 2021-09-29 22:20:03 +08:00
Cotes Chung
d9863d6a02 Separate the release steps from the bump tool 2021-09-29 22:18:38 +08:00
Cotes Chung
b460d03c3b Merge the test tool into the deploy tool 2021-09-29 22:18:38 +08:00
Cotes Chung
a053c454e4 Improve the init tool 2021-09-29 22:18:38 +08:00
Cotes Chung
77c2009658 Improve the layout of toc entries 2021-09-29 22:17:22 +08:00
Cotes Chung
9844b964a8 Improve the alignment of code block 2021-09-29 16:44:03 +08:00
Cotes Chung
063b2a6651 Prevent Disqus from jumping when page loading 2021-09-29 03:24:41 +08:00
Cotes Chung
e5df04dd59 Hide the scroll bar of code block when not hovering (resolve #414) 2021-09-29 03:24:41 +08:00
Cotes Chung
9e9278ce30 Fix code style of SCSS files 2021-09-24 15:35:44 +08:00
Cotes Chung
30dfc6fb7e Merge branch 'feature/icons-improvement' into develop 2021-09-24 15:32:35 +08:00
Cotes Chung
1ce350e33e Beautify the style of categories button 2021-09-24 15:21:49 +08:00
Cotes Chung
50c88f7205 Prevent the back-to-top button from flickering when switching the theme mode 2021-09-24 15:21:49 +08:00
Cotes Chung
387fc67102 Improve the vertical alignment of icons
- sidebar bottom icons
- back to top icon
2021-09-24 15:21:49 +08:00
Cotes Chung
414715fc47 Merge branch 'feature/code-snippet' into develop 2021-09-24 15:20:00 +08:00
Cotes Chung
1bb54096f4 Improve the UX of clipboard button 2021-09-24 15:13:00 +08:00
Cotes Chung
abb548fcee Change the icon & color of the code block header 2021-09-24 15:13:00 +08:00
Cotes Chung
ed93fbdfde Covert the language alias on code header 2021-09-24 15:13:00 +08:00
Cotes Chung
4ad0a76789 Add label icon to code snippet header 2021-09-24 15:13:00 +08:00
Cotes Chung
89b76dc2a0 Merge branch 'feature/color-scheme' into develop 2021-09-24 15:09:14 +08:00
Cotes Chung
395b24736a Improve the layout of sidebar icons 2021-09-24 14:54:15 +08:00
Cotes Chung
fa0155de6f Lighten the light mode color scheme 2021-09-23 20:39:16 +08:00
Cotes Chung
0bffb276fe Unlock Ruby 3.0 2021-09-22 01:22:32 +08:00
Cotes Chung
2417db656c Add aria label 2021-09-17 18:59:49 +08:00
Cotes Chung
e5bf234835 Fix cursor for some buttons & links (fix #411) 2021-09-17 16:58:32 +08:00
Cotes Chung
2dfdb66e0a Refactor clipboard functions 2021-09-17 16:08:00 +08:00
Cotes Chung
da9881a47f Merge branch 'hotfix/4.2.1' 2021-09-16 21:01:16 +08:00
Cotes Chung
c68a937e01 Improve the bump tool so that it can cherry-pick a merge type commit 2021-09-16 21:00:32 +08:00
Cotes Chung
4001ef7cba Prevent copying code line numbers on Safari 2021-09-16 18:42:50 +08:00
Cotes Chung
1b16b152df Optimize icon position 2021-09-16 17:56:12 +08:00
Cotes Chung
e607e5fe86 Restore the copy URL function that was deleted by mistake 2021-09-16 17:55:52 +08:00
Cotes Chung
d761d340a8 Bump version to 4.2.0 2021-09-16 01:40:38 +08:00
Cotes Chung
f411ba33d8 Fix code style 2021-09-16 01:19:40 +08:00
Cotes Chung
f722757f6f Update docs 2021-09-16 01:17:09 +08:00
Cotes Chung
beabb36d7f Add custom title to code block 2021-09-16 01:17:09 +08:00
Cotes Chung
42ff0f2282 Merge branch 'feature/improve-code-clipoard' into develop 2021-09-15 18:20:01 +08:00
Cotes Chung
34631a0c30 Update locale settings for code block clipboard (resolve #408) 2021-09-15 15:02:23 +08:00
Cotes Chung
53b0329e5a Improve the clipboard UX 2021-09-15 14:57:59 +08:00
Cotes Chung
2877896b9e Merge branch 'feature/improve-disqus' into develop 2021-09-14 20:47:01 +08:00
Cotes Chung
7ef88c8b8f Auto switch Disqus theme 2021-09-14 20:45:17 +08:00
Cotes Chung
2acf14ecf0 Replace Disqus lazy loading plugin with native JS 2021-09-14 20:45:17 +08:00
Cotes Chung
603705f20e Merge branch 'feature/beautify-scrollbar' into develop 2021-09-14 20:40:44 +08:00
Cotes Chung
0267ad8d40 Move sass variables 2021-09-14 20:40:16 +08:00
Cotes Chung
c0b8c089c2 Custom the scrollbar on Webkit browsers
the default scrollbar on Windows looks like shit
2021-09-14 16:47:11 +08:00
Cotes Chung
a603aac8e8 Merge branch 'feature/hide-lineno-of-code-block' into develop 2021-09-14 15:53:04 +08:00
Cotes Chung
91ed3d4649 Hide line number of some posts 2021-09-13 22:36:01 +08:00
Cotes Chung
20454e5a57 Add the feature of hiding line numbers 2021-09-13 22:26:17 +08:00
Cotes Chung
aadda0347c Merge branch 'feature/copy-snippet' (resolve #396, close #400) 2021-09-11 00:42:47 +08:00
Cotes Chung
5e9a7b319e Add clipboard JS 2021-09-11 00:30:21 +08:00
Cotes Chung
2537283beb Add clipboard button to code block 2021-09-11 00:30:21 +08:00
Cotes Chung
7dc7a7efc8 Add code block header 2021-09-11 00:30:21 +08:00
Cotes Chung
39b09b97c0 Merge branch 'feature/full-text-search' into develop 2021-09-04 21:24:37 +08:00
Cotes Chung
8d164c2e6e Enable full-text search (fix #401) 2021-09-04 21:23:43 +08:00
Cotes Chung
1a94b1889f Upgrade simple-jekyll-search from 1.7.3 to 1.10.0 2021-09-04 21:23:09 +08:00
Cotes Chung
6d07d4738b Remove margin between list items 2021-08-26 21:10:57 +08:00
Cotes Chung
6e0afcf9e8 Improve recognition of CJK 2021-08-26 01:26:16 +08:00
Cotes Chung
952927762a Run travis build only when tagging 2021-08-10 19:47:14 +08:00
Cotes Chung
3c3598e8b1 Reduce SASS compressed blank lines 2021-08-09 19:39:43 +08:00
Cotes Chung
9d9bca5e3b Improve the bump tool 2021-08-09 13:17:40 +08:00
Cotes Chung
03248f5bff Update comments for locales 2021-08-09 12:50:49 +08:00
Cotes Chung
e2c288a925 Add not results prompt in zh-CN 2021-08-09 12:49:59 +08:00
Maulana Kurniawan
b80d95dcdd Add Indonesian translation for search: no results. (#394)
Signed-off-by: maulanakurniawann <maulanakurniawan@outlook.co.id>
2021-08-09 12:46:23 +08:00
Cotes Chung
72ba1f7849 Fix tabs & improve topbar items 2021-08-03 22:55:35 +08:00
Hadian Alkani
46d80cbf9a Add Indonesian translation & locales (#390) 2021-08-03 16:58:12 +08:00
Cotes Chung
0213331a16 Improve the way to set the default value of locales 2021-08-01 22:04:11 +08:00
Cotes Chung
780af9ac5f Remove unused variable on HTML & JS 2021-08-01 21:49:44 +08:00
Cotes Chung
b513c0764d Update some locales value 2021-07-30 15:55:59 +08:00
Cotes Chung
57e8c6e594 Drop site config options content_lang & outdated 2021-07-30 15:55:59 +08:00
Cotes Chung
49dc866bd8 Fix docs 2021-07-22 01:30:26 +08:00
Cotes Chung
b7a483680e Bump version to 4.1.0 2021-07-22 00:51:20 +08:00
Cotes Chung
7ecb377c9b Update docs 2021-07-22 00:14:08 +08:00
Cotes Chung
a83e4c1b30 Optimize JS loading priority 2021-07-21 23:50:16 +08:00
Cotes Chung
0b29c0321f Add layout localization 2021-07-21 23:50:16 +08:00
Cotes Chung
2e76300d04 Revert "Delete useless SCSS snippets"
This reverts commit ab8cef9174.
2021-07-21 01:00:05 +08:00
Cotes Chung
20f2ff4b23 Update bot's reply message 2021-07-20 02:51:46 +08:00
Cotes Chung
899609a291 Switch to another issue bot 2021-07-20 02:26:03 +08:00
Cotes Chung
f56852a700 Fix breadcrumb for pagination 2021-07-20 02:08:28 +08:00
Cotes Chung
c969eaa040 Recover the missing image link identifier class 2021-07-20 02:08:28 +08:00
Cotes Chung
ab8cef9174 Delete useless SCSS snippets 2021-07-19 17:53:44 +08:00
Cotes Chung
b3ff6c79a6 Ignore the variables hook in the site file 2021-07-17 13:26:29 +08:00
Cotes Chung
7f8c19d480 Improve the code style on shell scripts
Double quote to prevent globbing and word splitting.
2021-07-11 17:26:49 +08:00
Cotes Chung
d52fa88337 Prevent the post date from shifting when loading 2021-07-11 17:04:13 +08:00
Cotes Chung
bea170cff0 Add fade in effect for lazy-loaded images 2021-07-11 15:05:18 +08:00
Cotes Chung
961ebb545b Set the dollar sign of code snippets to non-selectable 2021-07-08 21:19:33 +08:00
Cotes Chung
797450174d Dynamically detect the sass variables hook 2021-07-07 03:00:13 +08:00
FieryThunder
f0a2113a9f Fix typo of the issue template (#359) 2021-07-07 01:56:23 +08:00
Cotes Chung
c98a41317f Add a hook for custom variables (fix #355) 2021-07-04 23:24:30 +08:00
Cotes Chung
5f1e6e9350 Create the code language badge by Liquid
It prevents the language badges from flashing
2021-07-04 22:02:52 +08:00
Cotes Chung
65dbea9d3b Prevent image caption shifting
Before the image tag modified by JS, the caption will shift
2021-07-03 05:11:11 +08:00
Cotes Chung
fd97067ec3 Optimize the JS loading priorities 2021-07-03 05:11:11 +08:00
Cotes Chung
d5413a954f Update posts
- Set width and height for images
- Update the related tutorial
2021-07-03 05:11:11 +08:00
Cotes Chung
9359d6ef11 Ignore image links in html-proofer test 2021-07-02 17:14:40 +08:00
Cotes Chung
6d1d440c00 Preventing image reflow (fix #351) 2021-07-02 17:14:40 +08:00
Cotes Chung
08ec6cd3b5 Simplify the gitlab flow history 2021-06-24 21:30:05 +08:00
Cotes Chung
3ecb59deb1 Bump version to 4.0.2
(cherry picked from commit a6d4db251f)
2021-06-23 23:02:55 +08:00
Cotes Chung
885ed44646 Lock the ruby version number (#245, #247, #344)
Since version 3.0, Ruby has no `webrick` that Jekyll (<= 4.2) needs
2021-06-23 23:00:46 +08:00
Cotes Chung
d31e677ca0 Fix git-ignore list (#343) 2021-06-04 19:43:45 +08:00
blacksheep-git
bf3b539d6d Update 2019-08-08-text-and-typography.md
Fixed typo from 'Setction' to 'Section'.
2021-05-28 10:30:25 -06:00
Cotes Chung
ab927e9954 Improve sidebar cursor position calculation (fix #338) 2021-05-27 01:05:01 +08:00
Cotes Chung
d5e08b05ab Remove PR filter from workflow
GitHub does not allow to run workflows on PR from first-time contributors.
see: <https://docs.github.com/en/actions/managing-workflow-runs/approving-workflow-runs-from-public-forks>
2021-05-19 13:50:19 +08:00
Cotes Chung
eb247b8886 Improve the paginator design for the mobile screens (#331) 2021-05-19 11:09:52 +08:00
Cotes Chung
4fa7c6af6e Bump version to 4.0.1
(cherry picked from commit b887c439c6)
2021-05-08 03:26:04 +08:00
Cotes Chung
2cce0be8af Add the missing files to the gem 2021-05-08 03:19:13 +08:00
Cotes Chung
cf7d8a45ba Bump version to 4.0.0
(cherry picked from commit db82f71515)
2021-04-30 14:10:24 +08:00
Cotes Chung
6d254af55f Simplify the favicons 2021-04-29 19:58:37 +08:00
Cotes Chung
a4dc39f70e Center the mermaid SVG 2021-04-24 16:32:56 +08:00
Cotes Chung
84bb4d0c4b Add image popup effect 2021-04-24 16:32:56 +08:00
Cotes Chung
e8296fe2e4 Improve the site config 2021-04-20 04:34:11 +08:00
Cotes Chung
6a45d7ccd1 Remove SRI of bootstrap and font-awesome css
Sometimes it causes the fetch event to fail after the PWA cache key is updated:

```
The FetchEvent for "<url_from_CDN>" resulted in a network error response: an "opaque" response was used for a request whose type is not no-cors
```
2021-04-20 04:22:28 +08:00
Cotes Chung
5df67616be Fix the grammar and typo of the docs 2021-04-20 04:22:28 +08:00
Cotes Chung
f0ce5ceb71 Fix tabs url for service worker 2021-04-20 04:22:28 +08:00
Cotes Chung
a9acaa669d Reduce the external files required for gem installation 2021-04-20 04:22:28 +08:00
Cotes Chung
72e8ffafa6 Exclude JS source code from the output 2021-04-20 04:22:28 +08:00
Cotes Chung
52f4012463 Fix custom author name in RSS template 2021-04-18 03:21:55 +08:00
Cotes Chung
d5407181a4 Add shadow effect option for images 2021-04-18 03:15:11 +08:00
Cotes Chung
4ed6988be3 Globally mark out image links 2021-04-17 15:00:21 +08:00
Cotes Chung
3f2d400f16 Improve the selector for lazy loading images (fix #313)
When `page.dynamic_title` is set to false, the image will not be loaded
2021-04-13 23:29:24 +08:00
Cotes Chung
e84331b26a Fix the response stream of service worker
After service worker update (rebuild the site), the following error will occasionally appear:

```
The FetchEvent for "<url_from_CDN>" resulted in a network error response: an "opaque" response was used for a request whose type is not no-cors
```

This commit ensures that the response object has been cached before being returned.
2021-04-13 16:51:49 +08:00
Cotes Chung
efd8d44b12 Improve the UI design
- Optimize the text color in light mode
- Stop iOS Safari input field zooming
- Uniform font size for posts
2021-04-13 16:51:49 +08:00
Cotes Chung
a71659ed27 Fix bump tool 2021-04-12 13:34:01 +08:00
mattpopovich
b14e97a92d Small typo fix 2021-04-12 12:38:39 +08:00
Cotes Chung
826b7dca1a Turn off autocompletion of input form 2021-04-11 14:13:30 +08:00
Cotes Chung
d720d0f66c Bump version to 3.3.2
(cherry picked from commit 0b0e493ff0)
2021-04-11 01:39:27 +08:00
Cotes Chung
c1b8e28601 Fix links color in search results 2021-04-11 01:18:19 +08:00
Cotes Chung
aa54e901b1 Resume the pv cache source & add validation for the number of localStorage keys 2021-04-10 23:36:08 +08:00
Cotes Chung
a03149cd40 Reduce PWA storage space 2021-04-10 14:51:04 +08:00
Cotes Chung
588fbbbec7 Stop tracking Gemfile.lock in deployment tool (#306) 2021-04-07 15:15:17 +08:00
Cotes Chung
6341752986 Enhance detection of PV key validity in localStorage 2021-04-07 15:01:23 +08:00
Cotes Chung
11bcd7027d Fix dns links in head 2021-04-06 23:16:02 +08:00
Cotes Chung
4a0242e496 Simplify the PV config options
- Remove options `site.google_analytics.pv.enabled` and `site.google_analytics.pv.proxy_url`
- Rename options `site.google_analytics.pv.cache` to `site.google_analytics.pv.cache_path`
2021-04-06 23:15:36 +08:00
Cotes Chung
48e4c7e6d3 Fix the PV fetching failed when local cache is disabled
also improve the PV report logic
2021-04-06 02:32:53 +08:00
Cotes Chung
991f53f8b2 Unify the text color in the panel 2021-04-06 02:32:53 +08:00
Cotes Chung
7a5ad10bdc Optimize the responsive design for Pad devices 2021-04-06 02:32:53 +08:00
Cotes Chung
3b5441a1c2 Hide scrollbar of sidebar 2021-04-05 18:47:03 +08:00
Cotes Chung
a1fca3706f Update credits in README 2021-04-02 22:18:19 +08:00
Cotes Chung
49346fd3c6 Bump version to 3.3.1
(cherry picked from commit 0b043daa34)
2021-04-02 21:15:50 +08:00
Cotes Chung
bff97df3b5 Fix the MathJax config was lost in jekyll-compress-html 2021-04-02 21:14:43 +08:00
Cotes Chung
dbe4c3d42f Bump version to 3.3.0
(cherry picked from commit 41741dc336)
2021-04-02 16:17:40 +08:00
167 changed files with 3781 additions and 2742 deletions

View File

@@ -1,16 +1,43 @@
# How to Contribute
I want to thank you for sparing a time to improve this project! Here are some guidelines for contributing
We want 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 (e.g., `my-new-feature`, `fix-a-bug`).
3. After completing the development, submit a new _Pull Request_.
## Modifying JavaScript
If your contribution involves JS modification, please read the following sections.
### Inline Scripts
If you need to add comments to the inline JS (the JS code between the 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. And this will disrupt the structure of the compressed HTML.
### External Scripts
If you need to add or modify JavaScripts in the directory `_javascript`, you need to install [Gulp.js](https://gulpjs.com/docs/en/getting-started/quick-start).
During development, real-time debugging can be performed through the following commands:
```console
$ bash tools/run.sh
```
Open another terminal tab and run:
```console
$ gulp dev # Type 'Ctrl + C' to stop
```
After debugging, run the command `gulp` (without any argument) will automatically output the compressed files to the directory `assests/js/dist/`.
---
: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
View File

@@ -1,3 +1,2 @@
custom:
- https://www.buymeacoffee.com/coteschung
- https://cotes.gitee.io/alipay-wechat-donation
ko_fi: coteschung
custom: https://cotes.gitee.io/alipay-wechat-donation

View File

@@ -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,31 @@ 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 "` -->
- Theme version: <!-- by running: `gem list | grep 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 +60,5 @@ Steps to reproduce the behavior:
-->
### Additional context
<!-- Add any other context about the problem here. -->

View File

@@ -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. -->

View File

@@ -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 detial. -->
<!-- Please describe your question in detail. -->

View File

@@ -2,9 +2,9 @@
<!--
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
@@ -22,23 +22,21 @@ Please select the desired item checkbox and change it to "[x]", then delete opti
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/deploy.sh --dry-run` (at the root of the project) locally and passed
- [ ] I have tested this feature in the browser
### Test Configuration
- Browerser type & version:
- 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

View File

@@ -36,12 +36,5 @@ jobs:
ruby-version: 2.7
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/deploy.sh --dry-run

18
.github/workflows/issue-interceptor.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: Intercept bad issues
on:
issues:
types: [opened, edited]
jobs:
auto_close_issues:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Auto close issues that did not follow template
uses: lucasbento/auto-close-issues@v1.0.2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
issue-close-message: ":wave: Hi @${issue.user.login},\n\nThis issue is being automatically closed because it does not follow the issue template. Please DO NOT open another similar issue, try to edit the current issue according to the template, then it will be reopened automatically."
closed-issues-label: "🙁 Not following issue template"

View File

@@ -1,20 +0,0 @@
name: "Intercept bad issue/PRs"
on:
issues:
types: [opened]
pull_request:
types: [opened]
jobs:
autoclose:
runs-on: ubuntu-latest
steps:
- name: Auto close issues/pr that did not follow template
uses: roots/issue-closer@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-pattern: "(\\[x\\]|\\[X\\]) I have read"
issue-close-message: ":wave: Hi @${issue.user.login},\n\nThis issue is being automatically closed because it does not follow the issue template."
pr-pattern: "(\\[x\\]|\\[X\\]) (Bug fix|New feature|Breaking change|Documentation update)|@dependabot"
pr-close-message: ":wave: Hi @${pull_request.user.login},\n\nThis PR is being automatically closed because it does not follow the PR template."

View File

@@ -25,29 +25,5 @@ jobs:
ruby-version: 2.7
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
env:
JEKYLL_ENV: production
run: |
bundle exec jekyll b -d "_site$BASE_URL"
- name: Test Site
run: |
bash tools/test.sh
- name: Deploy
run: |
if [[ -n $BASE_URL ]]; then
mv _site$BASE_URL _site-rename
rm -rf _site
mv _site-rename _site
fi
bash tools/deploy.sh
run: bash tools/deploy.sh

5
.gitignore vendored
View File

@@ -1,6 +1,9 @@
# hidden files
.*
!.github
!.git*
!.editorconfig
!.nojekyll
!.travis.yml
# bundler cache
_site

1
.nojekyll Normal file
View File

@@ -0,0 +1 @@

View File

@@ -3,48 +3,41 @@ dist: bionic
language: minimal
branches:
only:
- /^release\/(\d)+(\.(\d)+){1}$/
jobs:
include:
- name: CD
- name: Deploy
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"
git:
depth: false # for posts' lastmod
- name: Flush Starter
script:
- eval "$FLUSH_STARTER"
script: eval "$FLUSH_STARTER"
before_script:
- git -C "$HOME" clone "$BUILDER_REPO" --depth=1 -q
branches:
only: /.*-stable$/
notifications:
email:
recipients:

View File

@@ -1,21 +0,0 @@
---
layout: page
title: "404: Page not found"
permalink: /404.html
redirect_from:
- /norobots/
- /assets/
- /posts/
dynamic_title: true
---
<div class="lead">
<p>Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. </p>
<p>
<a href="{{ '/' | relative_url }}">Head back Home</a>
to try finding it again, or search for it on the
<a href="{{ 'archives' | relative_url }}">Archives page</a>.
</p>
</div>

View File

@@ -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"

192
README.md
View File

@@ -1,205 +1,97 @@
# Chirpy
<div align="center">
Language: English | [简体中文](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/docs/README.zh-CN.md)
# Chirpy Jekyll Theme
[![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen)](https://rubygems.org/gems/jekyll-theme-chirpy)
[![Build Status](https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?branch=master&event=push)](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/8220b926db514f13afc3f02b7f884f4b)](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)
[![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg)](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
[![996.icu](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg)](https://996.icu)
A minimal, responsive, and powerful Jekyll theme for presenting professional writing.
A minimal, sidebar, responsive web design Jekyll theme that focuses on text presentation. Designed to help you record and share your knowledge easily. [Live Demo »](https://chirpy.cotes.info)
[![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen)](https://rubygems.org/gems/jekyll-theme-chirpy)
[![Build Status](https://github.com/cotes2020/jekyll-theme-chirpy/workflows/build/badge.svg?branch=master&event=push)](https://github.com/cotes2020/jekyll-theme-chirpy/actions?query=branch%3Amaster+event%3Apush)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/4e556876a3c54d5e8f2d2857c4f43894)](https://www.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cotes2020/jekyll-theme-chirpy&amp;utm_campaign=Badge_Grade)
[![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg)](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE)
[![996.icu](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg)](https://996.icu)
[![Devices Mockup](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png)](https://chirpy.cotes.info)
[**Live Demo →**](https://cotes2020.github.io/chirpy-demo)
[![Devices Mockup](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images@f4e0354b674f65a53b8917f0f786ed2956898cc1/commons/devices-mockup.png)](https://cotes2020.github.io/chirpy-demo)
</div>
## Features
- Localized Layout
- Dark/Light Theme Mode
- Pinned Posts
- Configurable theme mode
- Double-level Categories
- Last modified date for posts
- Hierarchical Categories
- Last Modified Date for Posts
- Table of Contents
- Automatically recommend related posts
- Syntax highlighting
- Mathematical expressions
- Mermaid diagram & flowchart
- Auto-generated Related Posts
- Syntax Highlighting
- Mathematical Expressions
- Mermaid Diagram & Flowchart
- Disqus/Utterances Comments
- Search
- Atom Feeds
- Disqus Comments
- Google Analytics
- GA Pageviews reporting (Advanced)
- SEO and Performance Optimization
- 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`.
## 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`.
There are two ways to get the theme:
### Step 1. Creating a New Site
- **Install from RubyGems** - Easy to update, isolate irrelevant project files so you can focus on writing.
- **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.
### Installing the Theme Gem
### 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
```
Finally, copy the required files from the theme's gem (for detailed files, see [starter project][starter]) to your Jekyll site.
### Step 3. Running Local Server
> **Hint**: To locate the installed themes gem, execute:
>
> ```console
> $ bundle info --path jekyll-theme-chirpy
> ```
Or you can [**use the starter template**][use-starter] to create a Jekyll site to save time copying files from theme's gem. We have prepared everything for you 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 extension `.hook` of `.github/workflows/pages-deploy.yml.hook`, and then remove the other files and directories in 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`
### 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 repoistory 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) throught _Settings__Options__GitHub Pages_:
![gh-pages-sources](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190809/gh-pages-sources.png)
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, the local service will be published at _<http://127.0.0.1:4000>_.
## Documentation
For more details and the better reading experience, please check out the [tutorials on 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).
For more details on usage, please refer to the tutorial on the [demo website](https://cotes2020.github.io/chirpy-demo/). At the same time, a copy of the tutorial is also available on the [Wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki). Please note that the tutorial is based on the [latest release](https://github.com/cotes2020/jekyll-theme-chirpy/releases), 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).
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.
Also, thank [JetBrains][jb] for providing the open source license.
Last but not least, thank [JetBrains][jb] for providing the open source 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!
[![Buy Me a Coffee](https://img.shields.io/badge/-Buy%20Me%20a%20Coffee-ff813f?logo=buy-me-a-coffee&logoColor=white)](https://www.buymeacoffee.com/coteschung)
[![Ko-fi](https://img.shields.io/badge/-Buy%20Me%20a%20Coffee-ff5f5f?logo=ko-fi&logoColor=white)](https://ko-fi.com/coteschung)
[![Wechat Pay](https://img.shields.io/badge/-Tip%20Me%20on%20WeChat-brightgreen?logo=wechat&logoColor=white)][cn-donation]
[![Alipay](https://img.shields.io/badge/-Tip%20Me%20on%20Alipay-blue?logo=alipay&logoColor=white)][cn-donation]
@@ -207,10 +99,6 @@ 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

View File

@@ -3,18 +3,21 @@
# 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 HTML language tag https://www.w3.org/International/questions/qa-choosing-language-tags
lang: en-US
# 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
# Change to your timezone http://www.timezoneconverter.com/cgi-bin/findzone/findzone
timezone: Asia/Shanghai
# jekyll-seo-tag settings https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md
# --------------------------
# --------------------------
title: Chirpy # the main title
tagline: A text-focused Jekyll theme # it will display as the sub-title
@@ -47,18 +50,16 @@ social:
# - https://www.linkedin.com/in/username
google_site_verification: google_meta_tag_verification # change to your verification string
# --------------------------
# ↑ --------------------------
google_analytics:
id: '' # Fill with your Google Analytics ID
id: '' # fill in your Google Analytics ID
# Google Analytics pageviews report settings
pv:
# The Google Analytics pageviews switch.
# DO NOT enable it unless you know how to deploy the Google Analytics superProxy.
enabled: false
# the next options only valid when `google_analytics.pv` is enabled.
proxy_url: ''
proxy_endpoint: ''
cache: false # pv data local cache, good for the users from GFW area.
proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine
cache_path: # the local PV cache data, friendly to visitors from GFW region
# Prefer color scheme setting.
#
@@ -78,17 +79,23 @@ 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://cdn.jsdelivr.net/gh/cotes2020/chirpy-images@f4e0354b674f65a53b8917f0f786ed2956898cc1'
# 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 | ...>
paginate: 10
@@ -105,16 +112,11 @@ kramdown:
line_numbers: true
start_line: 1
# DO NOT change this unless you're a Pro user on Jekyll and Web development,
# Or you think you're smart enough to change other relevant URLs within this template.
permalink: /posts/:title/
collections:
tabs:
output: true
sort_by: order
defaults:
-
scope:
@@ -124,6 +126,9 @@ defaults:
layout: post
comments: true # Enable comments in posts.
toc: true # Display TOC column in posts.
# 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:
path: _drafts
@@ -136,7 +141,6 @@ defaults:
values:
layout: page
permalink: /:title/
dynamic_title: true # Hide title in mobile screens.
sass:
style: compressed
@@ -151,9 +155,6 @@ compress_html:
envs: [development]
exclude:
- vendor
- Gemfile
- Gemfile.lock
- '*.gem'
- '*.gemspec'
- tools
@@ -162,8 +163,7 @@ exclude:
- LICENSE
- gulpfile.js
- node_modules
- package.json
- package-lock.json
- package*.json
jekyll-archives:
enabled: [categories, tags]

View File

@@ -2,7 +2,7 @@
-
type: github
icon: 'fab fa-github-alt'
icon: 'fab fa-github'
-
type: twitter
icon: 'fab fa-twitter'

View File

@@ -1,7 +0,0 @@
# The date format
tooltip: "%a, %b %e, %Y, %l:%M %p %z"
post:
long: "%b %e, %Y"
short: "%b %e"

View File

@@ -1,19 +0,0 @@
# The label text of site.
panel:
lastmod: Recent Update
trending_tags: Trending Tags
toc: Contents
post:
relate_posts: Further Reading
share: Share
button:
next: Newer
previous: Older
search_hint: Search # text show on search bar
pin_prompt: Pinned # pinned prompt
read_time_unit: min # see posts' time to read

91
_data/locales/en.yml Normal file
View File

@@ -0,0 +1,91 @@
# The layout text of site
# ----- Commons label -----
layout:
post: Post
category: Category
tag: Tag
# The tabs of sidebar
tabs:
# format: <filename_without_extension>: <value>
home: Home
categories: Categories
tags: Tags
archives: Archives
about: About
# the text displayed in the search bar & search results
search:
hint: search
cancel: Cancel
no_results: Oops! No result founds.
panel:
lastmod: Recent Update
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:
template: This post is licensed under :LICENSE_NAME by the author.
name: CC BY 4.0
link: https://creativecommons.org/licenses/by/4.0/
# Displayed in the footer
brief: Some rights reserved.
verbose: >-
Except where otherwise noted, the blog posts on this site are licensed
under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author.
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
# ----- Posts related labels -----
post:
written_by: By
posted: Posted
updated: Updated
timeago:
day: days ago
hour: hours ago
minute: minutes ago
just_now: just now
words: words
pageview_measure: views
read_time:
unit: min
prompt: read
relate_posts: Further Reading
share: Share
button:
next: Newer
previous: Older
copy_code:
succeed: Copied!
share_link:
title: Copy link
succeed: Link copied successfully!
# pinned prompt of posts list on homepage
pin_prompt: Pinned
# categories page
categories:
category_measure: categories
post_measure: posts

91
_data/locales/id-ID.yml Normal file
View File

@@ -0,0 +1,91 @@
# 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
# The liquid date format http://strftime.net/
date_format:
tooltip: "%a, %e %b, %Y, %l:%M %p"
post:
long: "%e %b, %Y"
short: "%e %b"
archive_month: "%b"
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.
hint_template: :HEAD_BAK untuk mencoba mencari kembali, atau cari di :ARCHIVES_PAGE.
head_back: Kembali ke Beranda
archives_page: Halaman Arsip
# ----- Posts related labels -----
post:
written_by: Oleh
posted: Diterbitkan
updated: Diperbarui
timeago:
day: hari yang lalu
hour: jam yang lalu
minute: menit yang lalu
just_now: baru saja
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

91
_data/locales/ko-KR.yml Normal file
View File

@@ -0,0 +1,91 @@
# 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: 바로가기
# The liquid date format http://strftime.net/
date_format:
tooltip: '%F, %R %z'
post:
long: '%Y년 %m월 %d일'
short: '%m월 %d일'
archive_month: '%b월'
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은 존재하지 않습니다.
hint_template: :HEAD_BAK을 눌러 다시 찾거나 :ARCHIVES_PAGE에서 검색해 주세요.
head_back: 홈으로 돌아가기
archives_page: 아카이브 페이지
# ----- Posts related labels -----
post:
written_by: By
posted: 게시
updated: 업데이트
timeago:
day: 일 전
hour: 시간 전
minute: 분 전
just_now: 방금
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: 포스트

90
_data/locales/zh-CN.yml Normal file
View File

@@ -0,0 +1,90 @@
# 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: 文章内容
# The liquid date format http://strftime.net/
date_format:
tooltip: '%F, %R %z'
post:
long: '%F'
short: '%m-%d'
archive_month: '%m月'
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: >-
除非另有说明,本网站上的博客文章均由作者按照知识共享署名 4.0 国际 (CC BY 4.0) 许可协议进行授权。
meta: 本站由 :PLATFORM 生成,采用 :THEME 主题。
not_found:
statment: 抱歉,我们放错了该 URL或者它指向了不存在的内容。
hint_template: :HEAD_BAK尝试再次查找它或在:ARCHIVES_PAGE上搜索它。
head_back: 返回主页
archives_page: 归档页面
# ----- Posts related labels -----
post:
written_by: 作者
posted: 发表于
updated: 更新于
timeago:
day: 天前
hour: 小时前
minute: 分钟前
just_now: 刚刚
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: 篇文章

View File

@@ -1,11 +0,0 @@
# License data
license:
name: CC BY 4.0
link: "https://creativecommons.org/licenses/by/4.0/"
brief: Some rights reserved.
verbose: >-
Except where otherwise noted, the blog posts on this site are licensed
under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author.

5
_includes/comments.html Normal file
View 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 %}

View 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() {
/* 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") {
/* modeToggle.addEventListener('click', reloadDisqus); // not pretty for 'color-scheme' */
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', reloadDisqus);
}
</script>

View 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[mode=dark]").length > 0
|| ($("html[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>

View File

@@ -8,3 +8,8 @@
<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 %}

View File

@@ -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>

View File

@@ -1,32 +1,17 @@
<!--
The Favicons for Web, Android, Microsoft, and iOS (iPhone and iPad) Apps
Generated by: https://www.favicon-generator.org/
Generated by: https://realfavicongenerator.net/
-->
{% capture icon_url %}{{ site.baseurl }}/assets/img/favicons{% endcapture %}
{% capture favicon_path %}{{ '/assets/img/favicons' | relative_url }}{% endcapture %}
<link rel="shortcut icon" href="{{ icon_url }}/favicon.ico" type="image/x-icon">
<link rel="icon" href="{{ icon_url }}/favicon.ico" type="image/x-icon">
<link rel="apple-touch-icon" href="{{ icon_url }}/apple-icon.png">
<link rel="apple-touch-icon" href="{{ icon_url }}/apple-icon-precomposed.png">
<link rel="apple-touch-icon" sizes="57x57" href="{{ icon_url }}/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="{{ icon_url }}/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="{{ icon_url }}/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="{{ icon_url }}/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="{{ icon_url }}/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="{{ icon_url }}/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="{{ icon_url }}/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="{{ icon_url }}/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="{{ icon_url }}/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="{{ icon_url }}/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="{{ icon_url }}/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="{{ icon_url }}/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="{{ icon_url }}/favicon-16x16.png">
<link rel="manifest" href="{{ icon_url }}/manifest.json">
<meta name='msapplication-config' content='{{ icon_url }}/browserconfig.xml'>
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="{{ icon_url }}/ms-icon-144x144.png">
<link rel="apple-touch-icon" sizes="180x180" href="{{ favicon_path }}/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="{{ favicon_path }}/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="{{ favicon_path }}/favicon-16x16.png">
<link rel="manifest" href="{{ favicon_path }}/site.webmanifest">
<link rel="shortcut icon" href="{{ favicon_path }}/favicon.ico">
<meta name="apple-mobile-web-app-title" content="{{ site.title }}">
<meta name="application-name" content="{{ site.title }}">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-config" content="{{ favicon_path }}/browserconfig.xml">
<meta name="theme-color" content="#ffffff">

View File

@@ -3,26 +3,33 @@
-->
<footer class="d-flex w-100 justify-content-center">
<div class="d-flex justify-content-between align-items-center">
<div class="d-flex justify-content-between align-items-center text-muted">
<div class="footer-left">
<p class="mb-0">
© {{ 'now' | date: "%Y" }}
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>.
{% if site.data.rights.brief %}
{% if site.data.locales[lang].copyright.brief %}
<span data-toggle="tooltip" data-placement="top"
title="{{ site.data.rights.verbose }}">{{ site.data.rights.brief }}</span>
title="{{ site.data.locales[lang].copyright.verbose }}">{{ site.data.locales[lang].copyright.brief }}</span>
{% endif %}
</p>
</div>
<div class="footer-right">
<p class="mb-0">
Powered by
<a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>
with
<a href="https://github.com/cotes2020/jekyll-theme-chirpy"
target="_blank" rel="noopener">Chirpy</a>
theme.
{% capture _platform %}
<a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a>
{% endcapture %}
{% capture _theme %}
<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener">Chirpy</a>
{% endcapture %}
{{ site.data.locales[lang].meta
| default: 'Powered by :PLATFORM with :THEME theme.'
| replace: ':PLATFORM', _platform | replace: ':THEME', _theme
}}
</p>
</div>

View File

@@ -7,19 +7,21 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
{% if page.layout == 'home' or page.layout == 'post' %}
<meta name="pv-cache-enabled" content="{{ site.google_analytics.pv.enabled }}">
{% if site.google_analytics.pv.enabled %}
{% if site.google_analytics.pv.proxy_endpoint != ''
and site.google_analytics.pv.proxy_endpoint %}
<meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}">
{% endif %}
{% if site.google_analytics.pv.cache %}
<meta name="pv-cache-data" content="{{ '/assets/js/data/pageviews.json' | relative_url }}">
{% endif %}
<!-- i18n for `_javascript/utils/timeago.js` -->
<meta name="day-prompt" content="{{ site.data.locales[lang].post.timeago.day }}">
<meta name="hour-prompt" content="{{ site.data.locales[lang].post.timeago.hour }}">
<meta name="minute-prompt" content="{{ site.data.locales[lang].post.timeago.minute }}">
<meta name="justnow-prompt" content="{{ site.data.locales[lang].post.timeago.just_now }}">
{% if site.google_analytics.pv.proxy_endpoint %}
<meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}">
{% endif %}
{% if site.google_analytics.pv.cache_path %}
<meta name="pv-cache-path" content="{{ site.google_analytics.pv.cache_path | relative_url }}">
{% endif %}
{% endif %}
{% seo title=false %}
@@ -45,36 +47,29 @@
<link rel="preconnect" href="https://www.googletagmanager.com" crossorigin="anonymous">
<link rel="dns-prefetch" href="https://www.googletagmanager.com">
{% if site.google_analytics.pv.proxy_url and site.google_analytics.pv.enabled %}
<link rel="preconnect" href="{{ site.google_analytics.pv.proxy_url }}" crossorigin="use-credentials">
<link rel="dns-prefetch" href="{{ site.google_analytics.pv.proxy_url }}">
{% if site.google_analytics.pv.proxy_endpoint %}
{% assign proxy_url = site.google_analytics.pv.proxy_endpoint
| 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="cdn.jsdelivr.net">
<link rel="dns-prefetch" href="cdn.jsdelivr.net">
<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"
integrity="sha256-LA89z+k9fjgMKQ/kq4OO2Mrf8VltYml/VES+Rg0fh20=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css">
<!-- Font Awesome -->
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.11.2/css/all.min.css"
integrity="sha256-+N4/V/SbAFiW1MPBCXnfnP9QSN3+Keu+NlB+0ev/YKQ="
crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.11.2/css/all.min.css">
{% include css-selector.html %}
<!-- JavaScripts -->
<!-- JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
<script defer
src="https://cdn.jsdelivr.net/combine/npm/popper.js@1.15.0,npm/bootstrap@4/dist/js/bootstrap.min.js"></script>
{% include js-selector.html %}
</head>

View File

@@ -2,20 +2,28 @@
JS selector for site.
-->
{% if page.layout == 'home' or page.layout == 'post' %}
{% if site.google_analytics.pv.enabled %}
<!-- layout specified -->
{% 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="{{ '/assets/js/dist/pvreport.min.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,npm/clipboard@2/dist/clipboard.min.js"></script>
{% endif %}
{% if page.layout == 'home'
or page.layout == 'categories'
or page.layout == 'post'
or page.layout == 'categories' %}
or page.layout == 'page' %}
{% assign type = page.layout %}
{% else %}
{% assign type = "page" %}
{% assign type = "commons" %}
{% endif %}
{% assign js = type | prepend: '/assets/js/dist/' | append: '.min.js' %}
@@ -24,14 +32,14 @@
{% if page.math %}
<!-- MathJax -->
<script>
// see: <https://docs.mathjax.org/en/latest/options/input/tex.html#tex-options>
/* see: <https://docs.mathjax.org/en/latest/options/input/tex.html#tex-options> */
MathJax = {
tex: {
inlineMath: [ // start/end delimiter pairs for in-line math
inlineMath: [ /* start/end delimiter pairs for in-line math */
['$','$'],
['\\(','\\)']
],
displayMath: [ // start/end delimiter pairs for display math
displayMath: [ /* start/end delimiter pairs for display math */
['$$', '$$'],
['\\[', '\\]']
]
@@ -44,6 +52,10 @@
</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>
{% if jekyll.environment == 'production' %}
<!-- PWA -->
<script defer src="{{ '/app.js' | relative_url }}"></script>

8
_includes/lang.html Normal file
View File

@@ -0,0 +1,8 @@
{% comment %}
Detect appearance language and return it through variable "lang"
{% endcomment %}
{% if site.data.locales[site.lang] %}
{% assign lang = site.lang %}
{% else %}
{% assign lang = 'en' %}
{% endif %}

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

View File

@@ -1,10 +0,0 @@
<!--
image lazy load: https://github.com/ApoorvSaxena/lozad.js
-->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/lozad/dist/lozad.min.js"></script>
<script type="text/javascript">
const imgs = document.querySelectorAll('.post-content img');
const observer = lozad(imgs);
observer.observe();
</script>

View File

@@ -3,8 +3,34 @@
-->
<script src="https://cdn.jsdelivr.net/npm/mermaid@8/dist/mermaid.min.js"></script>
<script>
$(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
@@ -25,5 +51,7 @@
});
mermaid.initialize(mermaidConf);
window.addEventListener("message", updateMermaid);
});
</script>

View File

@@ -2,14 +2,12 @@
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 DARK_MODE() { return "dark"; }
static get LIGHT_MODE() { return "light"; }
static get ID() { return "mode-toggle"; }
constructor() {
if (this.hasMode) {
@@ -24,10 +22,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,11 +41,33 @@
self.clearMode();
}
self.updateMermaid();
self.notify();
});
} /* constructor() */
get sysDarkPrefers() { return window.matchMedia("(prefers-color-scheme: dark)"); }
get isSysDarkPrefer() { return this.sysDarkPrefers.matches; }
get isDarkMode() { return this.mode === ModeToggle.DARK_MODE; }
get isLightMode() { return this.mode === ModeToggle.LIGHT_MODE; }
get hasMode() { return this.mode != null; }
get mode() { return sessionStorage.getItem(ModeToggle.MODE_KEY); }
/* get the current mode on screen */
get modeStatus() {
if (this.isDarkMode
|| (!this.hasMode && this.isSysDarkPrefer)) {
return ModeToggle.DARK_MODE;
} else {
return ModeToggle.LIGHT_MODE;
}
}
setDark() {
$('html').attr(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
@@ -64,82 +84,45 @@
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 isLightMode() { return this.mode == ModeToggle.LIGHT_MODE; }
get hasMode() { return this.mode != null; }
get mode() { return sessionStorage.getItem(ModeToggle.MODE_KEY); }
/* get the current mode on screen */
get modeStatus() {
if (this.isDarkMode
|| (!this.hasMode && this.isSysDarkPrefer) ) {
return ModeToggle.DARK_MODE;
} else {
return ModeToggle.LIGHT_MODE;
}
/* Notify another plugins that the theme mode has changed */
notify() {
window.postMessage({
direction: ModeToggle.ID,
message: this.modeStatus
}, "*");
}
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");
}
}
flipMode() {
if (this.hasMode) {
if (this.isSysDarkPrefer) {
if (this.isLightMode) {
this.clearMode();
} else {
this.setLight();
}
} else {
if (this.isDarkMode) {
this.clearMode();
} else {
this.setDark();
}
}
} else {
if (this.isSysDarkPrefer) {
this.setLight();
} else {
this.setDark();
}
}
this.updateMermaid();
} /* flipMode() */
} /* 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>

View File

@@ -0,0 +1,13 @@
{% 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', ' ' }}

View File

@@ -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.label.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.label.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.label.panel.toc | default: 'Contents' -}}
</span>
<nav id="toc" data-toggle="toc"></nav>
</div>
{% endif %}
</div> <!-- #panel-wrapper -->

View File

@@ -5,24 +5,24 @@
<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.label.post.button.previous | default: 'previous' }}">
prompt="{{ site.data.locales[lang].post.button.previous }}">
<p>{{ page.previous.title }}</p>
</a>
{% else %}
<span class="btn btn-outline-primary disabled"
prompt="{{ site.data.label.post.button.previous | default: 'previous' }}">
prompt="{{ site.data.locales[lang].post.button.previous }}">
<p>-</p>
</span>
{% endif %}
{% if page.next.url %}
<a href="{{ site.baseurl }}{{page.next.url}}" class="btn btn-outline-primary"
prompt="{{ site.data.label.post.button.next | default: 'next' }}">
prompt="{{ site.data.locales[lang].post.button.next }}">
<p>{{ page.next.title }}</p>
</a>
{% else %}
<span class="btn btn-outline-primary disabled"
prompt="{{ site.data.label.post.button.next | default: 'next' }}">
prompt="{{ site.data.locales[lang].post.button.next }}">
<p>-</p>
</span>
{% endif %}

View File

@@ -2,13 +2,14 @@
The paginator for post list on HomgPage.
-->
<ul class="pagination mt-4 mb-0 pl-lg-2">
<ul class="pagination align-items-center mt-4 mb-0 pl-lg-2">
<!-- left arrow -->
{% if paginator.previous_page %}
{% assign prev_url = paginator.previous_page_path | relative_url %}
{% else %}
{% assign prev_url = "#" %}
{% endif %}
<li class="page-item {% unless paginator.previous_page %}disabled{% endunless %}">
<a class="page-link btn-box-shadow" href="{{ prev_url }}" aria-label="previous-page">
<i class="fas fa-angle-left"></i>
@@ -65,12 +66,19 @@
{% endfor %}
<!-- mobile pagination -->
<li class="page-index align-middle">
<span>{{ paginator.page }}</span>
<span class="text-muted">/ {{ paginator.total_pages }}</span>
</li>
<!-- right arrow -->
{% if paginator.next_page_path %}
{% assign next_url = paginator.next_page_path | relative_url %}
{% else %}
{% assign next_url = "#" %}
{% endif %}
<li class="page-item {% unless paginator.next_page_path %}disabled{% endunless %}">
<a class="page-link btn-box-shadow" href="{{ next_url }}" aria-label="next-page">
<i class="fas fa-angle-right"></i>

View File

@@ -3,7 +3,7 @@
-->
<div class="share-wrapper">
<span class="share-label text-muted mr-1">{{ site.data.label.post.share | default: 'Share' }}</span>
<span class="share-label text-muted mr-1">{{ site.data.locales[lang].post.share }}</span>
<span class="share-icons">
{% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
{% assign url = page.url | absolute_url %}
@@ -16,8 +16,11 @@
</a>
{% endfor %}
<i class="fa-fw fas fa-link small" onclick="copyLink()"
data-toggle="tooltip" data-placement="top" title="Copy link"></i>
<i id="copy-link" class="fa-fw fas fa-link small"
data-toggle="tooltip" data-placement="top"
title="{{ site.data.locales[lang].post.button.share_link.title }}"
title-succeed="{{ site.data.locales[lang].post.button.share_link.succeed }}">
</i>
</span>
</div>

View File

@@ -1,9 +1,11 @@
<!--
Calculate the post's reading time, and display the word count in tooltip
-->
{% assign words = include.content | strip_html | number_of_words: "auto" %}
<!-- words per minute -->
{% assign wpm = 180 %}
{% assign min_time = 1 %}
@@ -13,7 +15,16 @@
{% assign read_time = min_time %}
{% endunless %}
{% capture read_prompt %}
{{- site.data.locales[lang].post.read_time.prompt -}}
{% endcapture %}
<!-- return element -->
<span class="readtime" data-toggle="tooltip" data-placement="bottom" title="{{ words }} words">
{{- read_time -}}{{" "}}{{- site.data.label.read_time_unit | default: "min" -}}
<span class="readtime" data-toggle="tooltip" data-placement="bottom"
title="{{ words }} {{ site.data.locales[lang].post.words }}">
<em>{{- read_time -}}{{" "}}{{- site.data.locales[lang].post.read_time.unit -}}</em>
{%- if include.prompt -%}
{%- assign _prompt_words = read_prompt | number_of_words: 'auto' -%}
{%- unless _prompt_words > 1 -%}{{ " " }}{%- endunless -%}{{ read_prompt }}
{%- endif -%}
</span>

View File

@@ -8,6 +8,7 @@
In order to allow a wide table to scroll horizontally,
we suround the markdown table with `<div class="table-wrapper">` and `</div>`
-->
{% if _content contains '<table>' %}
{% assign _content = _content
| replace: '<table>', '<div class="table-wrapper"><table>'
@@ -21,6 +22,7 @@
https://github.com/penibelst/jekyll-compress-html/issues/101
https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901
-->
{% if _content contains '<pre class="highlight">' %}
{% assign _content = _content
| replace: '<div class="highlight"><pre class="highlight"><code', '<div class="highlight"><code'
@@ -29,38 +31,200 @@
{% endif %}
<!-- Add attribute 'hide-bullet' to the checkbox list -->
{% if _content contains '<li class="task-list-item"><' %}
{% assign _content = _content
| replace: '"task-list-item"><', '"task-list-item" hide-bullet><'
%}
{% endif %}
{% if _content contains '<img src="' %}
<!-- images -->
{% 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 IMG_TAG = '<img ' %}
{% assign _content = _content | replace: '<img src="/', img_path_replacement %}
{% if _content contains IMG_TAG %}
{% assign _img_content = nil %}
{% assign _img_snippets = _content | split: IMG_TAG %}
<!-- lazy-load images <https://github.com/ApoorvSaxena/lozad.js#usage> -->
{% assign lozad = true %}
{% assign img_placehodler
= 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' %}
{% for _img_snippet in _img_snippets %}
{% if forloop.first %}
{% assign _img_content = _img_snippet %}
{% continue %}
{% endif %}
{% assign lozad_replacement = '<img src="'
| append: img_placehodler
| append: '" data-src="' %}
{% assign _width = nil %}
{% assign _height = nil %}
{% assign _src = nil %}
{% assign _content = _content | replace: '<img src="', lozad_replacement %}
{% 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 %}
{% 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 and _src %}
{% break %}
{% endif %}
{% endfor %}
{% if _src %}
{% unless _src contains '://' %}
<!-- Add CDN URL -->
{% if site.img_cdn %}
{% assign _src_prefix = site.img_cdn %}
{% else %}
{% assign _src_prefix = site.baseurl %}
{% endif %}
<!-- Add image path -->
{% if page.img_path %}
{% assign _path = page.img_path %}
{% assign last_char = _path | slice: -1 %}
{% unless last_char == '/' %}
{% assign _path = _path | append: '/' %}
{% endunless %}
{% 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 %}
{% assign _content = _img_content %}
{% endif %}
<!-- Add header for code snippets -->
{% 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 %}
{% else %}
{% 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 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" title-succeed="'
| append: site.data.locales[lang].post.button.copy_code.succeed
| append: '"><i class="far fa-clipboard"></i></button></div>'
| append: '<div class="highlight"><code>'
%}
{% endif %}
{% endfor %}
{% 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"><i class="fas fa-hashtag"></i></a>{% endcapture %}
{% assign left = snippet | split: mark_end | first %}
{% assign _start_index = left | size %}
{% assign _end_index = snippet | size | minus: 1 %}
{% assign right = snippet | slice: _start_index, _end_index %}
{% assign _new_content = _new_content | append: mark_start
| append: left | append: anchor | append: mark_end | append: right
%}
{% endfor %}
{% assign _heading_content = _new_content %}
{% endif %}
{% endfor %}
{% assign _content = _heading_content %}
<!-- return -->
{{ _content }}
{% if lozad %}
{% include lozad.html %}
{% endif %}
{{ _content }}

View File

@@ -81,7 +81,7 @@
{% 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.label.post.relate_posts | default: 'Further Reading' }}</h3>
data-toc-skip>{{ site.data.locales[lang].post.relate_posts }}</h3>
<div class="card-deck mb-4">
{% for entry in index_list %}
{% assign index = entry | plus: 0 %}
@@ -94,7 +94,7 @@
<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>

View File

@@ -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[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="https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js"></script>
<script>
SimpleJekyllSearch({

View File

@@ -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.label.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>

View File

@@ -2,38 +2,39 @@
The Side Bar
-->
<div id="sidebar" class="d-flex flex-column align-items-end">
<div id="sidebar" class="d-flex flex-column align-items-end" lang="{{lang}}">
<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'">
{% if site.avatar != '' and site.avatar %}
{% 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'">
{% endif %}
</a>
</div>
<div class="site-title mt-3">
<a href="{{ '/' | relative_url }}">{{- site.title -}}</a>
<a href="{{ '/' | relative_url }}">{{ site.title }}</a>
</div>
<div class="site-subtitle font-italic">{{- site.tagline -}}</div>
<div class="site-subtitle font-italic">{{ site.tagline }}</div>
</div><!-- .profile-wrapper -->
<ul class="w-100">
<!-- home -->
<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>{{ "HOME" }}</span>
<span>{{ site.data.locales[lang].tabs.home | upcase }}</span>
</a>
</li>
<!-- the real tabs -->
@@ -41,14 +42,26 @@
<li class="nav-item{% if tab.url == page.url %}{{ " active" }}{% endif %}">
<a href="{{ tab.url | relative_url }}" class="nav-link">
<i class="fa-fw {{ tab.icon }} ml-xl-3 mr-xl-3 unloaded"></i>
<span>{{ tab.title | upcase }}</span>
{% capture tab_name %}{{ tab.url | split: '/' }}{% endcapture %}
<span>{{ site.data.locales[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 %}
@@ -68,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>
@@ -76,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 -->

View File

@@ -1,31 +1,26 @@
<!--
Date format snippet
See: /assets/js/_utils/timeage.js
See: ${JS_ROOT}/utils/timeago.js
-->
{% assign tooltip_df = site.data.date_format.tooltip | default: '%a, %b %e, %Y, %l:%M %p %z' %}
{% assign post_long_df = site.data.date_format.post.long | default: '%b %e, %Y' %}
{% assign post_short_df = site.data.date_format.post.short | default: '%b %e' %}
{% assign tooltip_df = site.data.locales[lang].date_format.tooltip %}
{% assign post_long_df = site.data.locales[lang].date_format.post.long %}
{% assign post_short_df = site.data.locales[lang].date_format.post.short %}
<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 %}
<em class="timeago{% if include.class %} {{ include.class }}{% endif %}"
date="{{ include.date }}"
{% if include.tooltip %}
data-toggle="tooltip"
data-placement="bottom"
title="{{ include.date | date: tooltip_df }}"
{% endif %}>
{% if include.prefix %}prefix="{{ include.prefix }} "{% endif%}
{% if include.prep %}prep="{{ include.prep }}"{% endif %} >
{%- assign this_year = site.time | date: "%Y" -%}
{%- assign post_year = include.date | date: "%Y" -%}
{% assign this_year = site.time | date: "%Y" %}
{% assign post_year = include.date | date: "%Y" %}
{% if post_year == this_year %}
{%- if post_year == this_year -%}
{{ include.date | date: post_short_df }}
{% else %}
{%- else -%}
{{ include.date | date: post_long_df }}
{% endif %}
<i class="unloaded">{{ include.date | date_to_xmlschema }}</i>
</span>
{%- endif -%}
</em>

16
_includes/toc.html Normal file
View 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="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">
<div class="panel-heading pl-3 pt-2 mb-2">{{- site.data.locales[lang].panel.toc -}}</div>
<nav id="toc" data-toggle="toc"></nav>
</div>
{% endif %}

View File

@@ -8,34 +8,35 @@
{% assign paths = page.url | split: '/' %}
{% if paths.size == 0 %}
{% if paths.size == 0 or page.layout == 'home' %}
<!-- index page -->
<span>{{ 'Posts' }}</span>
<span>{{ site.data.locales[lang].tabs.home | capitalize }}</span>
{% else %}
{% for item in paths %}
{% if forloop.first %}
{% unless page.layout == 'post' %}
<span>
<a href="{{ '/' | relative_url }}">{{ 'Home' }}</a>
<a href="{{ '/' | relative_url }}">
{{ site.data.locales[lang].tabs.home | capitalize }}
</a>
</span>
{% endunless %}
{% elsif forloop.last %}
<span>{{ page.title }}</span>
{% else %}
<span>
{% assign url = item %}
{% if item == 'posts' and page.layout == 'post' %}
{% assign url = '/' %}
{% if page.collection == 'tabs' %}
<span>{{ site.data.locales[lang].tabs[item] | default: page.title }}</span>
{% else %}
<span>{{ page.title }}</span>
{% endif %}
<a href="{{ url | relative_url }}">
{{ item | capitalize }}
</a>
</span>
{% elsif page.layout == 'category' or page.layout == 'tag' %}
<span>
<a href="{{ item | relative_url }}">
{{ site.data.locales[lang].tabs[item] | default: page.title }}
</a>
</span>
{% endif %}
{% endfor %}
@@ -48,11 +49,12 @@
<div id="topbar-title">
{% if page.layout == 'home' %}
{{- site.title -}}
{% elsif page.dynamic_title %}
{{- page.title -}}
{{- site.data.locales[lang].title | default: site.title -}}
{% elsif page.collection == 'tabs' or page.dynamic_title %}
{%- capture tab_key -%}{{ page.url | split: '/' }}{%- endcapture -%}
{{- site.data.locales[lang].tabs[tab_key] | default: page.title -}}
{% else %}
{{- page.layout | capitalize -}}
{{- site.data.locales[lang].layout[page.layout] | default: page.layout | capitalize -}}
{% endif %}
</div>
@@ -60,10 +62,10 @@
<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" placeholder="{{ site.data.label.search_hint | default: 'Search' }}...">
aria-label="search" autocomplete="off" placeholder="{{ site.data.locales[lang].search.hint | capitalize }}...">
<i class="fa fa-times-circle fa-fw" id="search-cleaner"></i>
</span>
<span id="search-cancel" >Cancel</span>
<span id="search-cancel" >{{ site.data.locales[lang].search.cancel }}</span>
</div>
</div>

View File

@@ -34,3 +34,17 @@
{% endif %}
{% endfor %}
{% endfor %}
{% if trending_tags.size > 0 %}
<div id="access-tags">
<div class="panel-heading">{{- site.data.locales[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 %}

View File

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

View 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();
});
});

View File

@@ -0,0 +1,69 @@
/*
* Hide Header on scroll down
*/
$(function() {
const $topbarWrapper = $("#topbar-wrapper");
const $panel = $("#panel-wrapper");
const $searchInput = $("#search-input");
const CLASS_TOPBAR_UP = "topbar-up";
const CLASS_TOPBAR_DOWN = "topbar-down";
const ATTR_TOC_SCROLLING_UP = "toc-scrolling-up"; // topbar locked
let didScroll;
let lastScrollTop = 0;
const delta = $topbarWrapper.outerHeight();
const topbarHeight = $topbarWrapper.outerHeight();
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
if (st > topbarHeight) {
$topbarWrapper.removeClass(CLASS_TOPBAR_DOWN).addClass(CLASS_TOPBAR_UP);
$panel.removeClass(CLASS_TOPBAR_DOWN);
if ($searchInput.is(":focus")) {
$searchInput.blur(); /* remove focus */
}
}
} else {// Scroll up
// did not reach the bottom of the document, i.e., still have space to scroll up
if (st + $(window).height() < $(document).height()) {
let tocScrollingUp = $topbarWrapper.attr(ATTR_TOC_SCROLLING_UP);
if (typeof tocScrollingUp !== "undefined") {
if (tocScrollingUp === "false") {
$topbarWrapper.removeAttr(ATTR_TOC_SCROLLING_UP);
}
} else {
$topbarWrapper.removeClass(CLASS_TOPBAR_UP).addClass(CLASS_TOPBAR_DOWN);
$panel.addClass(CLASS_TOPBAR_DOWN);
}
}
}
lastScrollTop = st;
}
$(window).scroll(function(event) {
if ($("#topbar-title").is(":hidden")) {
didScroll = true;
}
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
});

5
_javascript/copyright Normal file
View File

@@ -0,0 +1,5 @@
/*!
* Chirpy v5.0.1 (https://github.com/cotes2020/jekyll-theme-chirpy/)
* © 2019 Cotes Chung
* MIT Licensed
*/

View File

@@ -0,0 +1,131 @@
/*
* 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 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('title-succeed');
$(btn).attr('data-original-title', succeedTitle).tooltip('show');
}
function hideTooltip(btn) {
$(btn).tooltip('hide').removeAttr('data-original-title');
}
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('data-original-title');
const succeedTitle = target.attr('title-succeed');
target.attr('data-original-title', succeedTitle).tooltip('show');
lock(target);
setTimeout(() => {
target.attr('data-original-title', defaultTitle);
unlock(target);
}, TIMEOUT);
});
});

View File

@@ -0,0 +1,47 @@
/**
Lazy load images (https://github.com/ApoorvSaxena/lozad.js)
and popup when clicked (https://github.com/dimsemenov/Magnific-Popup)
*/
$(function() {
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>`);
}
);
$('.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');
});

View File

@@ -0,0 +1,250 @@
/*
* Count page views form GA or local cache file.
*
* Dependencies:
* - jQuery
* - countUp.js <https://github.com/inorganik/countUp.js>
*/
const getInitStatus = (function () {
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]");
}
};
}());
const PvStorage = (function () {
const Keys = {
KEY_PV: "pv",
KEY_PV_SRC: "pv_src",
KEY_CREATION: "pv_created_date"
};
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;
}
}
}
};
}()); /* 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);
}
}
}
function countPV(path, rows) {
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;
}
}
}
return count;
}
function tacklePV(rows, path, elem, hasInit) {
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"));
}
}
}
function displayPageviews(data) {
if (typeof data === "undefined") {
return;
}
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);
});
} 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);
}
});
}
}
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));
});
}
$(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();
}
}
} else { // no cached
if (PvOpts.hasLocalMeta()) {
fetchLocalPageviews().then(fetchProxyPageviews);
} else {
fetchProxyPageviews();
}
}
});

View File

@@ -0,0 +1,101 @@
/*
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/>
Warning: It must be called after all `<a>` tags (e.g., the dynamic TOC) are ready.
*/
$(function() {
const $topbarWrapper = $("#topbar-wrapper");
const topbarHeight = $topbarWrapper.outerHeight();
const $topbarTitle = $("#topbar-title");
const ATTR_TOC_SCROLLING = "toc-scrolling-up";
const SCROLL_MARK = "scroll-focus";
const REM = 16; // in pixels
let tocScrollUpCount = 0;
$("a[href*='#']")
.not("[href='#']")
.not("[href='#0']")
.click(function(event) {
if (this.pathname.replace(/^\//, "") === location.pathname.replace(/^\//, "")) {
if (location.hostname === this.hostname) {
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 parent = $(this).parent().prop("tagName");
let isAnchor = RegExp(/^H\d/).test(parent);
let isMobileViews = !$topbarTitle.is(":hidden");
if (typeof $target !== "undefined") {
event.preventDefault();
if (history.pushState) { /* add hash to URL */
history.pushState(null, null, hash);
}
let curOffset = isAnchor? $(this).offset().top : $(window).scrollTop();
let destOffset = $target.offset().top -= REM / 2;
if (destOffset < curOffset) { // scroll up
if (!isAnchor && !toFootnote) { // trigger by ToC item
if (!isMobileViews) { // on desktop/tablet screens
$topbarWrapper.removeClass("topbar-down").addClass("topbar-up");
// Send message to `${JS_ROOT}/commons/topbar-switch.js`
$topbarWrapper.attr(ATTR_TOC_SCROLLING, true);
tocScrollUpCount += 1;
}
}
if ((isAnchor || toFootnoteRef) && isMobileViews) {
destOffset -= topbarHeight;
}
}
$("html").animate({
scrollTop: destOffset
}, 500, () => {
$target.focus();
/* clean up old scroll mark */
if ($(`[${SCROLL_MARK}=true]`).length) {
$(`[${SCROLL_MARK}=true]`).attr(SCROLL_MARK, false);
}
/* Clean :target links */
if ($(":target").length) { /* element that visited by the URL with hash */
$(":target").attr(SCROLL_MARK, false);
}
/* set scroll mark to footnotes */
if (toFootnote || toFootnoteRef) {
$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 (typeof $topbarWrapper.attr(ATTR_TOC_SCROLLING) !== "undefined") {
tocScrollUpCount -= 1;
if (tocScrollUpCount <= 0) {
$topbarWrapper.attr(ATTR_TOC_SCROLLING, "false");
}
}
});
}
}
}
}); /* click() */
});

View File

@@ -0,0 +1,77 @@
/*
* Calculate the Timeago
*/
$(function() {
const timeagoElem = $(".timeago");
let tasks = timeagoElem.length;
let intervalId = void 0;
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(date, initDate) {
let now = new Date();
let past = new Date(date);
if (past.getFullYear() !== now.getFullYear()
|| past.getMonth() !== now.getMonth()) {
return initDate;
}
let seconds = Math.floor((now - past) / 1000);
let day = Math.floor(seconds / 86400);
if (day >= 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)[0].hasAttribute("date") === false) {
tasks -= 1;
return;
}
let date = $(this).attr("date");
let initDate = $(this).text();
let relativeDate = timeago(date, initDate);
if (relativeDate === initDate) {
$(this).removeAttr("date");
} else {
$(this).text(relativeDate);
}
});
if (tasks === 0 && typeof intervalId !== "undefined") {
clearInterval(intervalId); /* stop interval */
}
return tasks;
}
if (tasks === 0) {
return;
}
if (updateTimeago() > 0) { /* run immediately */
intervalId = setInterval(updateTimeago, 60000); /* run every minute */
}
});

View File

@@ -3,8 +3,10 @@ layout: page
# The Archives of posts.
---
{% include lang.html %}
<div id="archives" class="pl-xl-2">
{% for post in site.posts %}
{% capture this_year %}{{ post.date | date: "%Y" }}{% endcapture %}
{% capture pre_year %}{{ post.previous.date | date: "%Y" }}{% endcapture %}
@@ -17,9 +19,10 @@ layout: page
<li>
<div>
{% capture this_day %}{{ post.date | date: "%d" }}{% endcapture %}
{% capture this_month %}{{ post.date | date: "%b" }}{% endcapture %}
{% capture _mth_df %}{{ site.data.locales[lang].date_format.post.archive_month }}{% endcapture %}
{% capture this_month %}{{ post.date | date: _mth_df }}{% endcapture %}
<span class="date day">{{ this_day }}</span>
<span class="date month small text-muted">{{ this_month }}</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>

View File

@@ -3,6 +3,7 @@ layout: page
# All the Categories of posts
---
{% include lang.html %}
{% assign HEAD_PREFIX = "h_" %}
{% assign LIST_PREFIX = "l_" %}
@@ -33,28 +34,23 @@ layout: page
<div class="card categories">
<!-- top-category -->
<div class="card-header d-flex justify-content-between hide-border-bottom"
id="{{ HEAD_PREFIX }}{{ group_index }}">
<div id="{{ HEAD_PREFIX }}{{ group_index }}"
class="card-header d-flex justify-content-between hide-border-bottom">
<span>
{% if sub_categories_size > 0 %}
<i class="far fa-folder-open fa-fw"></i>
{% else %}
<i class="far fa-folder fa-fw"></i>
{% endif %}
<a href="{{ site.baseurl }}/categories/{{ category_name | slugify | url_encode }}/"
class="ml-1 mr-2">
{{ category_name }}
</a>
<i class="far fa-folder{% if sub_categories_size > 0 %}-open{% endif %} fa-fw"></i>
{% capture _category_url %}/categories/{{ category_name | slugify | url_encode }}/{% endcapture %}
<a href="{{ _category_url | relative_url }}" class="ml-1 mr-2">{{ category_name }}</a>
<!-- content count -->
{% assign top_posts_size = site.categories[category_name] | size %}
<span class="text-muted small font-weight-light">
{% if sub_categories_size > 0 %}
{{ sub_categories_size }}
{% if sub_categories_size > 1 %}categories{% else %}category{% endif %},
{{ site.data.locales[lang].categories.category_measure }},
{% endif %}
{{ top_posts_size }}
post{% if top_posts_size > 1 %}s{% endif %}
{{ site.data.locales[lang].categories.post_measure }}
</span>
</span>
@@ -80,11 +76,14 @@ layout: page
{% for sub_category in sub_categories %}
<li class="list-group-item">
<i class="far fa-folder fa-fw"></i>
<a href="{{ site.baseurl }}/categories/{{ sub_category | slugify | url_encode }}/"
class="ml-1 mr-2">{{ sub_category }}</a>
{% capture _sub_ctg_url %}/categories/{{ sub_category | slugify | url_encode }}/{% endcapture %}
<a href="{{ _sub_ctg_url | relative_url }}" class="ml-1 mr-2">{{ sub_category }}</a>
{% assign posts_size = site.categories[sub_category] | size %}
<span class="text-muted small font-weight-light">{{ posts_size }}
post{% if posts_size > 1 %}s{% endif %}
<span class="text-muted small font-weight-light">
{{ posts_size }}
{{ site.data.locales[lang].categories.post_measure }}
</span>
</li>
{% endfor %}

View File

@@ -3,6 +3,8 @@ layout: page
# The Category layout
---
{% include lang.html %}
<div id="page-category">
<h1 class="pl-lg-2">
<i class="far fa-folder-open fa-fw text-muted"></i>
@@ -11,13 +13,13 @@ layout: page
</h1>
<ul class="post-content pl-0">
{% assign post_long_df = site.data.date_format.post.long | default: '%b %e, %Y' %}
{% assign post_df = site.data.locales[lang].date_format.post.long %}
{% 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_long_df }}</span>
<span class="text-muted small">{{ post.date | date: post_df }}</span>
</li>
{% endfor %}
</ul>

View File

@@ -5,16 +5,22 @@ layout: compress
<!DOCTYPE html>
{% include lang.html %}
{% capture prefer_mode %}
{% if site.theme_mode %}
mode="{{ site.theme_mode }}"
{% endif %}
{% endcapture %}
<html lang="{{ site.lang | default: "en-US" }}" {{ prefer_mode }}>
<html lang="{{ site.lang }}"{{ prefer_mode }}>
{% include head.html %}
{% unless site.theme_mode %}
{% include mode-toggle.html %}
{% endunless %}
<body data-spy="scroll" data-target="#toc">
{% include sidebar.html %}
@@ -24,7 +30,7 @@ layout: compress
<div id="main-wrapper">
<div id="main">
{% include refactor-content.html content=content %}
{{ content }}
{% include footer.html %}
@@ -46,6 +52,8 @@ layout: compress
{% include search-loader.html %}
{% include js-selector.html %}
</body>
</html>

View File

@@ -3,9 +3,11 @@ layout: page
# The Home page layout
---
{% include lang.html %}
{% assign pinned = site.posts | where: "pin", "true" %}
{% assign default = site.posts | where_exp: "item", "item.pin != true" %}
{% assign pinned = site.posts | where_exp: "item", "item.pin == true" %}
{% assign default = site.posts | where_exp: "item", "item.pin != true" %}
{% assign posts = "" | split: "" %}
<!-- Get pinned posts -->
@@ -39,7 +41,6 @@ layout: page
{% endfor %}
{% endif %}
<div id="post-list">
{% for post in posts %}
@@ -52,13 +53,13 @@ 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>
<div class="mr-auto">
<!-- posted date -->
<i class="far fa-calendar fa-fw"></i>
{% include timeago.html date=post.date tooltip=true %}
@@ -67,19 +68,22 @@ layout: page
<i class="far fa-clock fa-fw"></i>
{% include read-time.html content=post.content %}
<!-- page views -->
{% if site.google_analytics.pv.enabled %}
<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.label.pin_prompt | default: 'Pinned' }}</span>
<span>{{ site.data.locales[lang].post.pin_prompt }}</span>
</div>
{% endif %}

View File

@@ -1,34 +1,64 @@
---
layout: default
# The page layout
---
{% include lang.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 %}
<h1 class="dynamic-title">{{ page.title }}</h1>
<div class="post-content">
<!-- core -->
<div id="core-wrapper" class="col-12 col-lg-11 col-xl-8">
<div class="post pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
{% 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 title = site.data.locales[lang].tabs[tab_key] | default: page.title %}
<h1 class="dynamic-title">
{{ title }}
</h1>
<div class="post-content">
{{ _content }}
</div>
{% else %}
{{ content }}
{{ _content }}
{% endif %}
</div> <!-- #page -->
</div><!-- .col-12 -->
{% include panel.html %}
</div>
</div> <!-- #core-wrapper -->
<!-- pannel -->
<div id="panel-wrapper" class="col-xl-3 pl-2 text-muted topbar-down">
<div class="access">
{% include update-list.html %}
{% include trending-tags.html %}
</div>
{% for _include in layout.pannel_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 id="tail-wrapper" class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
{% for _include in layout.tail_includes %}
{% assign _include_path = _include | append: '.html' %}
{% include {{ _include_path }} %}
{% endfor %}
</div>
</div>
</div> <!-- .row -->
{% endif %}

View File

@@ -1,129 +1,144 @@
---
layout: default
# The posts' layout
layout: page
refactor: true
pannel_includes:
- toc
tail_includes:
- related-posts
- post-nav
- comments
---
<div class="row">
{% include lang.html %}
<div id="post-wrapper" class="col-12 col-lg-11 col-xl-8">
{% if page.image.src %}
{% capture bg %}
{% unless page.image.no_bg %}{{ 'bg' }}{% endunless %}
{% endcapture %}
<img src="{{ page.image.src }}" class="preview-img {{ bg | strip }}"
alt="{{ page.image.alt | default: "Preview Image" }}"
<div class="post pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
{% if page.image.width %}
width="{{ page.image.width }}"
{% elsif page.image.w %}
width="{{ page.image.w }}"
{% endif %}
<h1 data-toc-skip>{{ page.title }}</h1>
{% if page.image.height %}
height="{{ page.image.height }}"
{% elsif page.image.h %}
height="{{ page.image.h }}"
{% endif %}>
{% endif %}
<div class="post-meta text-muted d-flex flex-column">
<!-- Published date and author -->
<div>
<span class="semi-bold">
{{ page.author | default: site.social.name }}
</span>
{% include timeago.html date=page.date prep="on" tooltip=true %}
</div>
<h1 data-toc-skip>{{ page.title }}</h1>
<div>
<!-- lastmod -->
{% if page.last_modified_at %}
<span>
{% include timeago.html date=page.last_modified_at
class="lastmod" prefix="Updated" tooltip=true %}
</span>
{% endif %}
<div class="post-meta text-muted">
<!-- read time -->
{% include read-time.html content=content %}
<!-- author -->
<div>
{% capture author_name %}{{ page.author.name | default: site.social.name }}{% endcapture %}
{% assign author_link = nil %}
<!-- page views -->
{% if site.google_analytics.pv.enabled %}
<span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin fa-fw"></i></span>
{% endif %}
</div>
</div> <!-- .post-meta -->
<div class="post-content">
{% if page.image.src %}
<img src="{{ page.image.src }}" class="preview-img" alt="{{ page.image.alt | default: "Preview Image" }}">
{% endif %}
{{ content }}
</div>
<div class="post-tail-wrapper text-muted">
<!-- categories -->
{% if page.categories.size > 0 %}
<div class="post-meta mb-3">
<i class="far fa-folder-open fa-fw mr-1"></i>
{% for category in page.categories %}
<a href='{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/'>{{ category }}</a>
{%- unless forloop.last -%}, {%- endunless -%}
{% endfor %}
</div>
{% endif %}
<!-- tags -->
{% if page.tags.size > 0 %}
<div class="post-tags">
<i class="fa fa-tags fa-fw mr-1"></i>
{% for tag in page.tags %}
<a href="{{ site.baseurl }}/tags/{{ tag | slugify | url_encode }}/"
class="post-tag no-text-decoration" >
{{- tag -}}
</a>
{% endfor %}
</div>
{% endif %}
<div class="post-tail-bottom
d-flex justify-content-between align-items-center mt-3 pt-5 pb-2">
{% if site.data.rights.license %}
<div class="license-wrapper">
This post is licensed under
<a href="{{ site.data.rights.license.link }}">{{ site.data.rights.license.name }}</a>
by the author.
</div>
{% endif %}
{% include post-sharing.html %}
</div><!-- .post-tail-bottom -->
</div><!-- div.post-tail -->
</div> <!-- .post -->
</div> <!-- #post-wrapper -->
{% assign enable_toc = false %}
{% if site.toc and page.toc %}
{% if content contains '<h2' or content contains '<h3' %}
{% assign enable_toc = true %}
{% if page.author.link %}
{% assign author_link = page.author.link %}
{% elsif author_name == site.social.name %}
{% assign author_link = site.social.links[0] %}
{% endif %}
{{ site.data.locales[lang].post.written_by }}
<em>
{% if author_link %}
<a href="{{ author_link }}">{{ author_name }}</a>
{% else %}
{{ author_name }}
{% endif %}
</em>
</div>
<div class="d-flex">
<div>
<!-- published date -->
<span>
{{ site.data.locales[lang].post.posted }}
{% include timeago.html date=page.date tooltip=true %}
</span>
<!-- lastmod date -->
{% if page.last_modified_at %}
<span>
{{ site.data.locales[lang].post.updated }}
{% include timeago.html date=page.last_modified_at tooltip=true %}
</span>
{% endif %}
<!-- read time -->
{% include read-time.html content=content prompt=true %}
<!-- page views -->
{% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
<span>
<em id="pv" class="pageviews">
<i class="fas fa-spinner fa-spin fa-fw"></i>
</em>
{{ site.data.locales[lang].post.pageview_measure }}
</span>
{% endif %}
</div>
</div> <!-- .d-flex -->
</div> <!-- .post-meta -->
<div class="post-content">
{{ content }}
</div>
<div class="post-tail-wrapper text-muted">
<!-- categories -->
{% if page.categories.size > 0 %}
<div class="post-meta mb-3">
<i class="far fa-folder-open fa-fw mr-1"></i>
{% for category in page.categories %}
<a href='{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/'>{{ category }}</a>
{%- unless forloop.last -%}, {%- endunless -%}
{% endfor %}
</div>
{% endif %}
{% include panel.html toc=enable_toc %}
<!-- tags -->
{% if page.tags.size > 0 %}
<div class="post-tags">
<i class="fa fa-tags fa-fw mr-1"></i>
{% for tag in page.tags %}
<a href="{{ site.baseurl }}/tags/{{ tag | slugify | url_encode }}/"
class="post-tag no-text-decoration" >
{{- tag -}}
</a>
{% endfor %}
</div>
{% endif %}
</div> <!-- .row -->
<div class="post-tail-bottom
d-flex justify-content-between align-items-center mt-3 pt-5 pb-2">
<div class="license-wrapper">
<div class="row">
<div class="col-12 col-lg-11 col-xl-8">
<div id="post-extend-wrapper" class="pl-1 pr-1 pl-sm-2 pr-sm-2 pl-md-4 pr-md-4">
{% if site.data.locales[lang].copyright.license.template %}
{% include related-posts.html %}
{% capture _replacement %}
<a href="{{ site.data.locales[lang].copyright.license.link }}">
{{ site.data.locales[lang].copyright.license.name }}
</a>
{% endcapture %}
{% include post-nav.html %}
{{ site.data.locales[lang].copyright.license.template | replace: ':LICENSE_NAME', _replacement }}
{% if site.disqus.comments and page.comments %}
{% include disqus.html %}
{% endif %}
{% endif %}
</div>
</div> <!-- #post-extend-wrapper -->
{% include post-sharing.html %}
</div> <!-- .col-* -->
</div><!-- .post-tail-bottom -->
</div> <!-- .row -->
</div><!-- div.post-tail-wrapper -->

View File

@@ -3,6 +3,7 @@ layout: page
# The layout for Tag page
---
{% include lang.html %}
<div id="page-tag">
<h1 class="pl-lg-2">
@@ -11,13 +12,13 @@ layout: page
<span class="lead text-muted pl-2">{{ page.posts | size }}</span>
</h1>
<ul class="post-content pl-0">
{% assign post_long_df = site.data.date_format.post.long | default: '%b %e, %Y' %}
{% assign post_df = site.data.locales[lang].date_format.post.long %}
{% 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_long_df }}</span>
<span class="text-muted small">{{ post.date | date: post_df }}</span>
</li>
{% endfor %}
</ul>

View File

@@ -1,13 +1,17 @@
---
title: Text and Typography
author: Cotes Chung
author:
name: Cotes Chung
link: https://github.com/cotes2020
date: 2019-08-08 11:33:00 +0800
categories: [Blogging, Demo]
tags: [typography]
math: true
mermaid: true
image:
src: https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/commons/devices-mockup.png
src: /commons/devices-mockup.png
width: 800
height: 500
---
This post is to show Markdown syntax rendering on [**Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork), you can also use it as an example of writing. Now, let's start looking at text and typography.
@@ -50,14 +54,13 @@ Fluttering and dancing in the breeze.
### Unordered list
- Chapter
- Setcion
- Paragraph
- Section
- Paragraph
### Task list
- [ ] TODO
- [x] Completed
- Hold on
- [ ] Defeat COVID-19
- [x] Vaccine production
- [ ] Economic recovery
@@ -71,7 +74,6 @@ Sun
Moon
: the natural satellite of the earth, visible by reflected light from the sun
## Block Quote
> This line to shows the Block Quote.
@@ -88,44 +90,42 @@ Moon
<http://127.0.0.1:4000>
## Footnote
Click the hook will locate the footnote[^footnote], and here is another footnote[^fn-nth-2].
## Images
- Default (with caption)
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png)
![Desktop View](/posts/20190808/mockup.png){: width="972" height="589" }
_Full screen width and center alignment_
<br>
- Specify width
- Shadow
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="400"}
_400px image width_
![Window shadow](/posts/20190808/window.png){: .shadow width="1548" height="864" style="max-width: 90%" }
_shadow effect (visible in light mode)_
<br>
- Left aligned
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="350" .normal}
![Desktop View](/posts/20190808/mockup.png){: width="972" height="589" style="max-width: 70%" .normal}
<br>
- Float to left
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="240" .left}
![Desktop View](/posts/20190808/mockup.png){: width="972" height="589" style="max-width: 200px" .left}
"A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space."
<br>
- Float to right
![Desktop View](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190808/mockup.png){: width="240" .right}
![Desktop View](/posts/20190808/mockup.png){: width="972" height="589" style="max-width: 200px" .right}
"A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space. A repetitive and meaningless text is used to fill the space."
<br>
@@ -140,7 +140,6 @@ _400px image width_
cherry :active, c, after b a, 1d
```
## Mathematics
The mathematics powered by [**MathJax**](https://www.mathjax.org/):
@@ -151,12 +150,10 @@ When $a \ne 0$, there are two solutions to $ax^2 + bx + c = 0$ and they are
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
## Inline code
This is an example of `Inline Code`.
## Code block
### Common
@@ -175,44 +172,23 @@ SHELL=/usr/local/bin/bash
PYENV_SHELL=bash
```
#### Ruby
```ruby
def sum_eq_n?(arr, n)
return true if arr.empty? && n == 0
arr.product(arr).reject { |a,b| a == b }.any? { |a,b| a + b == n }
end
```
#### Shell
```shell
```bash
if [ $? -ne 0 ]; then
echo "The command was not successful.";
#do the needful / exit
fi;
```
#### Liquid
### Specific filename
{% raw %}
```liquid
{% if product.title contains 'Pack' %}
This product's title contains the word Pack.
{% endif %}
```
{% endraw %}
#### Java
```java
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out any hidden serialization magic
s.defaultWriteObject();
for (E e: map.keySet()) s.writeObject(e);
}
```sass
@import
"colors/light-typography",
"colors/dark-typography"
```
{: file='_sass/jekyll-theme-chirpy.scss'}
## Reverse Footnote

View File

@@ -1,14 +1,19 @@
---
title: Writing a New Post
author: Cotes Chung
author:
name: Cotes Chung
link: https://github.com/cotes2020
date: 2019-08-08 14:10:00 +0800
categories: [Blogging, Tutorial]
tags: [writing]
render_with_liquid: false
---
This post will guide you how to write a post on _Chirpy_ theme. Even if you have previous experience with Jekyll, this article is worth reading, because many features require specific variables to be set.
## Naming and Path
Create a new file named `YYYY-MM-DD-TITLE.EXTENSION` and put it in the `_posts/` of the root directory. Please note that the `EXTENSION` must be one of `md` and `markdown`.
Create a new file named `YYYY-MM-DD-TITLE.EXTENSION` and put it in the `_posts` of the root directory. Please note that the `EXTENSION` must be one of `md` and `markdown`. If you want to save time of creating files, please consider using the plugin [`Jekyll-Compose`](https://github.com/jekyll/jekyll-compose) to accomplish this.
## Front Matter
@@ -23,24 +28,38 @@ tags: [TAG] # TAG names should always be lowercase
---
```
> **Note**: The posts' ***layout*** has been set to `post` by default, so there is no need to add the variable ***layout*** in Front Matter block.
> **Note**: The posts' _layout_ has been set to `post` by default, so there is no need to add the variable _layout_ in the Front Matter block.
### Timezone of date
### Timezone of Date
In order to accurately record the release date of a post, you should not only setup the `timezone` of `_config.yml` but also provide the the post's timezone in field `date` of its Front Matter block. Format: `+/-TTTT`, e.g. `+0800`.
In order to accurately record the release date of a post, you should not only set up the `timezone` of _\_config.yml_ but also provide the post's timezone in variable `date` of its Front Matter block. Format: `+/-TTTT`, e.g. `+0800`.
### Categories and Tags
The `categories` of each post is designed to contain up to two elements, and the number of elements in `tags` can be zero to infinity. For instance:
The `categories` of each post are designed to contain up to two elements, and the number of elements in `tags` can be zero to infinity. For instance:
```yaml
---
categories: [Animal, Insect]
tags: [bee]
---
```
### Author Information
The author information of the post usually does not need to be filled in the _Front Matter_ , they will be obtained from variables `social.name` and the first entry of `social.links` of the configuration file by default. But you can also override it as follows:
```yaml
---
author:
name: Full Name
link: https://example.com
---
```
## Table of Contents
By default, the **T**able **o**f **C**ontents (TOC) is displayed on the right panel of the post. If you want to turn it off globally, go to `_config.yml` and set the value of variable `toc` to `false`. If you want to turn off TOC for specific post, add the following to post's [Front Matter](https://jekyllrb.com/docs/front-matter/):
By default, the **T**able **o**f **C**ontents (TOC) is displayed on the right panel of the post. If you want to turn it off globally, go to _\_config.yml_ and set the value of variable `toc` to `false`. If you want to turn off TOC for a specific post, add the following to the post's [Front Matter](https://jekyllrb.com/docs/front-matter/):
```yaml
---
@@ -50,7 +69,9 @@ toc: false
## Comments
Similar to TOC, the [Disqus](https://disqus.com/) comments is loaded by default in each post, and the global switch is defined by variable `comments` in file `_config.yml` . If you want to close the comment for specific post, add the following to the **Front Matter** of the post:
The global switch of comments is defined by variable `comments.active` in the file _\_config.yml_. After selecting a comment system for this variable, comments will be turned on for all posts.
If you want to close the comment for a specific post, add the following to the **Front Matter** of the post:
```yaml
---
@@ -72,29 +93,17 @@ math: true
[**Mermaid**](https://github.com/mermaid-js/mermaid) is a great diagrams generation tool. To enable it on your post, add the following to the YAML block:
```yml
```yaml
---
mermaid: true
---
```
Then you can use it like other markdown language: surround the graph code with ```` ```mermaid ```` and ```` ``` ````.
Then you can use it like other markdown languages: surround the graph code with ```` ```mermaid ```` and ```` ``` ````.
## Images
### Preview image
If you want to add an image to the top of the post contents, specify the url and alt attribute for the image:
```yaml
---
image:
src: /path/to/image/file
alt: image alternative text
---
```
### Image caption
### Caption
Add italics to the next line of an imagethen it will become the caption and appear at the bottom of the image:
@@ -102,62 +111,130 @@ Add italics to the next line of an imagethen it will become the caption and a
![img-description](/path/to/image)
_Image Caption_
```
{: .nolineno}
### Image size
### Size
You can specify the width (and height) of a image with `width`:
In order to prevent the page content layout from shifting when the image is loaded, we should set the width and height for each image:
```markdown
![Desktop View](/assets/img/sample/mockup.png){: width="400"}
![Desktop View](/assets/img/sample/mockup.png){: width="700" height="400" }
```
{: .nolineno}
### Image position
Starting from _Chirpy v5.0.0_, `height` and `width` support abbreviations (`height` → `h`, `width` → `w`). The following example has the same effect as the above:
By default, the image is centered, but you can specify the position by using one of class `normal` , `left` and `right`. For example:
```markdown
![Desktop View](/assets/img/sample/mockup.png){: w="700" h="400" }
```
{: .nolineno}
### Position
By default, the image is centered, but you can specify the position by using one of the classes `normal`, `left`, and `right`. For example:
- **Normal position**
Image will be left aligned in below sample:
```markdown
![Desktop View](/assets/img/sample/mockup.png){: .normal}
![Desktop View](/assets/img/sample/mockup.png){: .normal }
```
{: .nolineno}
- **Float to the left**
```markdown
![Desktop View](/assets/img/sample/mockup.png){: .left}
![Desktop View](/assets/img/sample/mockup.png){: .left }
```
{: .nolineno}
- **Float to the right**
```markdown
![Desktop View](/assets/img/sample/mockup.png){: .right}
![Desktop View](/assets/img/sample/mockup.png){: .right }
```
{: .nolineno}
**Limitation**: Once you specify the position of an image, it is forbidden to add the image caption.
> **Limitation**: Once the position of the image is specified, the image caption should not be added.
### Shadow
The screenshots of the program window can be considered to show the shadow effect, and the shadow will be visible in the `light` mode:
```markdown
![Desktop View](/assets/img/sample/mockup.png){: .shadow }
```
{: .nolineno}
### CDN URL
If you host the images on the CDN, you can save the time of repeatedly writing the CDN url by assigning the variable `img_cdn` of `_config.yml` file:
If you host the images on the CDN, you can save the time of repeatedly writing the CDN URL by assigning the variable `img_cdn` of _\_config.yml_ file:
```yaml
img_cdn: https://cdn.com
```
{: file='_config.yml' .nolineno}
Once `img_cdn` is assigned, the CDN url will be added to the path of all images (images of site avatar and posts) starting with `/`.
Once `img_cdn` is assigned, the CDN URL will be added to the path of all images (images of site avatar and posts) starting with `/`.
For instance, when using images:
```markdown
![The flower](/path/to/flower.png)
```
{: .nolineno}
The parsing result will automatically add the CDN prefix `https://cdn.com` before the image path:
```html
<img src="https://cdn.com/path/to/flower.png" alt="The flower">
```
{: .nolineno}
### Image Path
When a post contains many images, it will be a time-consuming task to repeatedly define the path of the images. To solve this, we can define this path in the YAML block of the post:
```yml
---
img_path: /img/path/
---
```
{: .nolineno }
And then, the image source of Markdown can write the file name directly:
```md
![The flower](flower.png)
```
{: .nolineno }
The output will be:
```html
<img src="/img/path/flower.png" alt="The flower">
```
{: .nolineno }
### Preview Image
If you want to add an image to the top of the post contents, specify the attribute `src`, `width`, `height`, and `alt` for the image:
```yaml
---
image:
src: /path/to/image/file
width: 1000 # in pixels
height: 400 # in pixels
alt: image alternative text
---
```
Except for `alt`, all other options are necessary, especially the `width` and `height`, which are related to user experience and web page loading performance. The above section "[Size](#size)" also mentions this.
Starting from _Chirpy v5.0.0_, the attributes `height` and `width` can be abbreviated: `height` → `h`, `width` → `w`. In addition, the [`img_path`](#image-path) can also be passed to the preview image, that is, when it has been set, the attribute `src` only needs the image file name.
## Pinned Posts
@@ -171,31 +248,51 @@ pin: true
## Code Block
Markdown symbols ```` ``` ```` can easily create a code block as following examples.
Markdown symbols ```` ``` ```` can easily create a code block as follows:
```
This is a common code snippet, without syntax highlight and line number.
This is a plaintext code snippet.
```
## Specific Language
### Specifying Language
Using ```` ```language ```` you will get code snippets with line numbers and syntax highlight.
> **Note**: The Jekyll style `{% raw %}{%{% endraw %} highlight LANGUAGE {% raw %}%}{% endraw %}` or `{% raw %}{%{% endraw %} highlight LANGUAGE linenos {% raw %}%}{% endraw %}` are not allowed to be used in this theme !
Using ```` ```{language} ```` you will get a code block with syntax highlight:
````markdown
```yaml
# Yaml code snippet
items:
- part_no: A4786
descrip: Water Bucket (Filled)
price: 1.47
quantity: 4
key: value
```
````
> **Limitation**: The Jekyll style `highlight` tag is not compatible with this theme.
### Line Number
By default, all languages except `plaintext`, `console`, and `terminal` will display line numbers. When you want to hide the line number of the code block, you can append `{: .nolineno}` at the next line:
````markdown
```shell
echo 'No more line numbers!'
```
{: .nolineno}
````
### Specifying the Filename
You may have noticed that the code language will be displayed on the left side of the header of the code block. If you want to replace it with the file name, you can add the attribute `file` to achieve this:
````markdown
```shell
# content
```
{: file="path/to/file" }
````
### Liquid Codes
If you want to display the **Liquid** snippet, surround the liquid code with `{% raw %}{%{% endraw %} raw {%raw%}%}{%endraw%}` and `{% raw %}{%{% endraw %} endraw {%raw%}%}{%endraw%}` .
If you want to display the **Liquid** snippet, surround the liquid code with `{% raw %}` and `{% endraw %}`:
````markdown
{% raw %}
```liquid
{% if product.title contains 'Pack' %}
@@ -203,8 +300,10 @@ If you want to display the **Liquid** snippet, surround the liquid code with `{%
{% endif %}
```
{% endraw %}
````
Or adding `render_with_liquid: false` (Requires Jekyll 4.0 or higher) to the post's YAML block.
## Learn More
For more knowledge about Jekyll posts, visit the [Jekyll Docs: Posts](https://jekyllrb.com/docs/posts/).

View File

@@ -1,6 +1,8 @@
---
title: Getting Started
author: Cotes Chung
author:
name: Cotes Chung
link: https://github.com/cotes2020
date: 2019-08-09 20:55:00 +0800
categories: [Blogging, Tutorial]
tags: [getting started]
@@ -9,54 +11,24 @@ pin: true
## Prerequisites
Follow the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll` and `Bundler`.
Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll`, and `Bundler`.
## Installation
There are two ways to get the theme:
### Creating a New Site
- **Install from RubyGems** - Easy to update, isolate irrelevant project files so you can focus on writing.
- **Fork on GitHub** - Convenient for custom development, but difficult to update, only suitable for web developers.
There are two ways to create a new repository for this theme:
### Installing the Theme Gem
- [**Using the Chirpy Starter**](#option-1-using-the-chirpy-starter) - Easy to upgrade, isolates irrelevant project files so you can focus on writing.
- [**Forking on GitHub**](#option-2-forking-on-github) - Convenient for custom development, but difficult to upgrade. Unless you are familiar with Jekyll and are determined to tweak or contribute to this project, this approach is not recommended.
Add this line to your Jekyll site's `Gemfile`:
#### Option 1. Using the Chirpy Starter
```ruby
gem "jekyll-theme-chirpy"
```
Create a new repository from the [**Chirpy Starter**][use-starter] and name it `<GH_USERNAME>.github.io`, where `GH_USERNAME` represents your GitHub username.
And add this line to your Jekyll site's `_config.yml`:
#### Option 2. Forking on GitHub
```yaml
theme: jekyll-theme-chirpy
```
And then execute:
```console
$ bundle
```
Finally, copy the required files from the theme's gem (for detailed files, see [starter project][starter]) to your Jekyll site.
> **Hint**: To locate the installed themes gem, execute:
>
> ```console
> $ bundle info --path jekyll-theme-chirpy
> ```
Or you can [**use the starter template**][use-starter] to create a Jekyll site to save time copying files from theme's gem. We have prepared everything for you 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
```
[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) on GitHub and rename it to `<GH_USERNAME>.github.io`. Please note that the default branch code is in development. If you want the site to be stable, please switch to the [latest tag][latest-tag] and start writing.
And then execute:
@@ -64,18 +36,28 @@ And then execute:
$ 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.
> **Note**: If you don't want to deploy your site on GitHub Pages, append option `--no-gh` at the end of the above command.
What it does is:
The above command will:
1. Remove some files or directories from your repository:
1. Removes 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 extension `.hook` of `.github/workflows/pages-deploy.yml.hook`, and then remove the other files and directories in folder `.github`.
2. If the option `--no-gh` is provided, the directory `.github` will be deleted. Otherwise, set up 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.
3. Removes item `Gemfile.lock` from `.gitignore`.
4. Creates a new commit to save the changes automatically.
### Installing Dependencies
Before running for the first time, go to the root directory of your site, and install dependencies as follows:
```console
$ bundle
```
## Usage
@@ -88,6 +70,12 @@ Update the variables of `_config.yml` as needed. Some of them are typical option
- `timezone`
- `lang`
### Customing Stylesheet
If you need to customize the 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`][chirpy-4.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:
@@ -98,55 +86,62 @@ $ bundle exec jekyll s
Or run the site on Docker with the following command:
```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>_.
After a while, the local service will be published at _<http://127.0.0.1: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`.
Before the deployment begins, check out 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 starts 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
#### Deploy by Using Github Actions
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.
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 GitHub 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.
- Ensure your Jekyll site has the file `.github/workflows/pages-deploy.yml`. Otherwise, create a new one and fill in the contents of the [sample file][workflow], and the value of the `on.push.branches` should be the same as your repo's default branch name.
And then rename your repoistory to `<GH-USERNAME>.github.io` on GitHub.
- Ensure your Jekyll site has file `tools/deploy.sh`. Otherwise, copy it from here to your Jekyll site.
- Furthermore, if you have committed `Gemfile.lock` to the repo, and your runtime system is not Linux, don't forget to update the platform list in the lock file:
```console
$ bundle lock --add-platform x86_64-linux
```
After the above steps, 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) throught _Settings__Options__GitHub Pages_:
2. Browse to your repository on GitHub. Select the tab _Settings_, then click _Pages_ in the left navigation bar, and then in the section **Source** of _GitHub Pages_, select the `/(root)` directory of branch `gh-pages` as the [publishing source][pages-src]. Remember to click <kbd>Save</kbd> before leaving.
![gh-pages-sources](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190809/gh-pages-sources.png)
![gh-pages-sources](/posts/20190809/gh-pages-sources.png){: width="1580" height="250" }
3. Visit your website at the address indicated by GitHub.
#### Deploy on Other Platforms
#### Manually Build and Deploy
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.
On self-hosted servers, you cannot enjoy the convenience of **GitHub Actions**. Therefore, you should build the site on your local machine and then upload the site files to the server.
Go to the root of the source project, build your site by:
Go to the root of the source project, and build your site as follows:
```console
$ JEKYLL_ENV=production bundle exec jekyll b
```
Or build the site with Docker by:
Or build the site on Docker:
```terminal
```console
$ docker run -it --rm \
--env JEKYLL_ENV=production \
--volume="$PWD:/srv/jekyll" \
@@ -154,8 +149,34 @@ $ docker run -it --rm \
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.
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 the target server.
### Upgrading
It depends on how you use the theme:
- If you are using the theme gem (there will be `gem "jekyll-theme-chirpy"` in the `Gemfile`), editing the `Gemfile` and update the version number of the theme gem, for example:
```diff
- gem "jekyll-theme-chirpy", "~> 3.2", ">= 3.2.1"
+ gem "jekyll-theme-chirpy", "~> 3.3", ">= 3.3.0"
```
{: .nolineno file="Gemfile" }
And then execute the following command:
```console
$ bundle update jekyll-theme-chirpy
```
As the version upgrades, the critical files (for details, see the [Startup Template][starter]) and configuration options will change. Please refer to the [Upgrade Guide](https://github.com/cotes2020/jekyll-theme-chirpy/wiki/Upgrade-Guide) to keep your repo's files in sync with the latest version of the theme.
- If you forked from the source project (there will be `gemspec` in the `Gemfile` of your site), then merge the [latest upstream tags][latest-tag] into your Jekyll site to complete the upgrade.
The merge is likely to conflict with your local modifications. Please be patient and careful to resolve these conflicts.
[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
[chirpy-4.1.0]: https://github.com/cotes2020/jekyll-theme-chirpy/releases/tag/v4.1.0
[pages-src]: https://docs.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site
[latest-tag]: https://github.com/cotes2020/jekyll-theme-chirpy/tags

View File

@@ -1,39 +1,37 @@
---
title: Customize the Favicon
author: Cotes Chung
author:
name: Cotes Chung
link: https://github.com/cotes2020
date: 2019-08-11 00:34:00 +0800
categories: [Blogging, Tutorial]
tags: [favicon]
toc: false
---
In [**Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/), the image files of [Favicons](https://www.favicon-generator.org/about/) are placed in `assets/img/favicons/`. You may need to replace them with your own. So let's see how to customize these Favicons.
The [favicons](https://www.favicon-generator.org/about/) of [**Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/) are placed in the directory `assets/img/favicons/`. You may want to replace them with your own. The following sections will guide you to create and replace the default favicons.
With a square image (PNG, JPG or GIF) in hand, open the site [*Favicon & App Icon Generator*](https://www.favicon-generator.org/) and upload your original image.
## Generate the favicon
![upload-image](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190811/upload-image.png)
Prepare a square image (PNG, JPG, or SVG) with a size of 512x512 or more, and then go to the online tool [**Real Favicon Generator**](https://realfavicongenerator.net/) and click the button <kbd>Select your Favicon image</kbd> to upload your image file.
Click button <kbd>Create Favicon</kbd> and wait a moment for the website to generate the icons of various sizes automatically.
In the next step, the webpage will show all usage scenarios. You can keep the default options, scroll to the bottom of the page, and click the button <kbd>Generate your Favicons and HTML code</kbd> to generate the favicon.
![download-icons](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20190811/download-icons.png){: width="600"}
## Download & Replace
Download the generated package, unzip and delete the following two from the extracted files:
- browserconfig.xml
- manifest.json
- `browserconfig.xml`
- `site.webmanifest`
Now, copy the remaining image files (`.PNG` and `.ICO`) from the extracted `.zip` file to cover the original files in the folder `assets/img/favicons/`.
And then copy the remaining image files (`PNG` and `ICO`) to cover the original files in the directory `assets/img/favicons/` of your Jekyll site. If your Jekyll site doesn't have this directory yet, just create one.
The following table helps you understand the changes to the icon file:
The following table will help you understand the changes to the favicon files:
> ✓ means keep, ✗ means delete.
| File(s) | From Favicon & App Icon Generator | From Chirpy |
| File(s) | From Online Tool | From Chirpy |
|---------------------|:---------------------------------:|:-----------:|
| `*.PNG` | ✓ | ✗ |
| `*.ICO` | ✓ | ✗ |
| `browserconfig.xml` | ✗ | ✓ |
| `manifest.json` | ✗ | ✓ |
> Note: ✓ means keep, ✗ means delete.
The next time you build the site, the icon will be replaced with a customized edition.
The next time you build the site, the favicon will be replaced with a customized edition.

View File

@@ -1,61 +1,61 @@
---
title: Enable Google Page Views
author: Dinesh Prasanth Moluguwan Krishnamoorthy
author:
name: Dinesh Prasanth Moluguwan Krishnamoorthy
link: https://github.com/SilleBille
date: 2021-01-03 18:32:00 -0500
categories: [Blogging, Tutorial]
tags: [google analytics, pageviews]
---
This post is to enable Page Views on the [**Chirpy**][chirpy-homepage] theme based blog that you just built. This requires technical knowledge and it's recommended to keep the `google_analytics.pv` disabled unless you have a good reason. If your website has low traffic, the page views count would discourage you to write more blogs. With that said, let's start with the setup.
This post is to enable Page Views on the [**Chirpy**][chirpy-homepage] theme based blog that you just built. This requires technical knowledge and it's recommended to keep the `google_analytics.pv.*` empty unless you have a good reason. If your website has low traffic, the page views count would discourage you to write more blogs. With that said, let's start with the setup.
## Set up Google Analytics
### Create GA account and property
First, you need to setup your account on Google analytics. While your create your account, you must create your first **Property** as well.
First, you need to set up your account on Google analytics. While you create your account, you must create your first **Property** as well.
1. Head to <https://analytics.google.com/> and click on **Start Measuring**
2. Enter your desired _Account Name_ and choose the desired checkboxes
3. Enter your desired _Property Name_. This is the name of the tracker project that appears on your Google Analytics dashboard
4. Enter the required information _About your business_
5. Hit _Create_ and accept any license popup to setup your Google Analytics account and create your property
5. Hit _Create_ and accept any license popup to set up your Google Analytics account and create your property
### Create Data Stream
With your property created, you now need to set up Data Stream to track your blog traffic. After you signup, the prompt should automatically take you to creating your first **Data Stream**. If not, follow these steps:
With your property created, you now need to set up Data Stream to track your blog traffic. After you signup, the prompt should automatically take you to create your first **Data Stream**. If not, follow these steps:
1. Go to **Admin** on the left column
2. Select the desired property from the drop down on the second column
2. Select the desired property from the drop-down on the second column
3. Click on **Data Streams**
4. Add a stream and click on **Web**
5. Enter your blog's URL
It should look like this:
![google-analytics-data-stream](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/01-google-analytics-data-stream.png)
![google-analytics-data-stream](/posts/20210103/01-google-analytics-data-stream.png){: width="1086" height="542"}
Now, click on the new data stream and grab the **Measurement ID**. It should look something like `G-V6XXXXXXXX`. Copy this to your `_config.yml` file
```yaml
google_analytics:
id: 'G-V6XXXXXXX' # Fill with your Google Analytics ID
id: 'G-V6XXXXXXX' # fill in your Google Analytics ID
# Google Analytics pageviews report settings
pv:
# The Google Analytics pageviews switch.
enabled: false
# the next options only valid when `google_analytics.pv` is enabled.
proxy_url: ''
proxy_endpoint: ''
cache: false # pv data local cache, good for the users from GFW area.
proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine
cache_path: # the local PV cache data, friendly to visitors from GFW region
```
{: file="_config.yml"}
When you push these changes to your blog, you should start seeing the traffic on your Google Analytics. Play around with Google Analytics dashboard to get familiar with the options available as it takes like 5 mins to pickup your changes. You should now be able to monitor your traffic in realtime.
When you push these changes to your blog, you should start seeing the traffic on your Google Analytics. Play around with the Google Analytics dashboard to get familiar with the options available as it takes like 5 mins to pick up your changes. You should now be able to monitor your traffic in real time.
![google-analytics-realtime](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/02-google-analytics-realtime.png)
![google-analytics-realtime](/posts/20210103/02-google-analytics-realtime.png){: width="616" height="557"}
## Setup Page Views
There is a detailed [tutorial](https://developers.google.com/analytics/solutions/google-analytics-super-proxy) available to set up Google Analytics superProxy. But, if you are interested to just quickly get your Chirpy-based blog display page views, follow along. These steps were tested on a Linux machine. If you are running Windows, you can use Git bash terminal to run Unix-like commands.
There is a detailed [tutorial](https://developers.google.com/analytics/solutions/google-analytics-super-proxy) available to set up Google Analytics superProxy. But, if you are interested to just quickly get your Chirpy-based blog display page views, follow along. These steps were tested on a Linux machine. If you are running Windows, you can use the Git bash terminal to run Unix-like commands.
### Setup Google App Engine
@@ -69,7 +69,7 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
5. Select **Python** language and **Standard** environment
6. Enable billing account. Yeah, you have to link your credit card. But, you won't be billed unless you exceed your free quota. For a simple blog, free quota is more than sufficient.
6. Enable billing account. Yeah, you have to link your credit card. But, you won't be billed unless you exceed your free quota. For a simple blog, the free quota is more than sufficient.
7. Go to your App Engine dashboard on your browser and select **API & Services** from the left navigation menu
@@ -79,7 +79,7 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
10. On the left, Click on _OAuth Consent Screen_ and accept **Configure Consent Screen**. Select **External** since your blog is probably hosted for the public. Click on **Publish** under _Publishing Status_
11. Click on **Credentials** on the left and create a new **OAuth Client IDs** credential. Make sure to add a entry under `Authorized redirect URIs` that matches: `https://<project-id>.<region>.r.appspot.com/admin/auth`
11. Click on **Credentials** on the left and create a new **OAuth Client IDs** credential. Make sure to add an entry under `Authorized redirect URIs` that matches: `https://<project-id>.<region>.r.appspot.com/admin/auth`
12. Note down the **Your Client ID** and **Your Client Secret**. You'll need this in the next section.
@@ -115,15 +115,16 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
1. Clone the **Google Analytics superProxy** project on Github: <https://github.com/googleanalytics/google-analytics-super-proxy> to your local.
2. Remove the first 2 lines in the [`src/app.yaml`](https://github.com/googleanalytics/google-analytics-super-proxy/blob/master/src/app.yaml#L1-L2) file:
```diff
- application: your-project-id
- version: 1
```
2. Remove the first 2 lines in the [`src/app.yaml`](https://github.com/googleanalytics/google-analytics-super-proxy/blob/master/src/app.yaml#L1-L2) file:
3. In `src/config.py`, add the `OAUTH_CLIENT_ID` and `OAUTH_CLIENT_SECRET` that you gathered from you App Engine Dashboard.
```diff
- application: your-project-id
- version: 1
```
4. Enter any random key for `XSRF_KEY`, your `config.py` should look similar to this
3. In `src/config.py`, add the `OAUTH_CLIENT_ID` and `OAUTH_CLIENT_SECRET` that you gathered from your App Engine Dashboard.
4. Enter any random key for `XSRF_KEY`, your `config.py` should look similar to this
```python
#!/usr/bin/python2.7
@@ -143,10 +144,11 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
# XSRF Settings
XSRF_KEY = 'OnceUponATimeThereLivedALegend'
```
{: file="src/config.py"}
**Tip:** You can configure a custom domain instead of `https://PROJECT_ID.REGION_ID.r.appspot.com`. But, for the sake of keeping it simple, we will be using the Google provided default URL.
5. From inside the src/ directory, deploy the app
5. From inside the src/ directory, deploy the app
```console
[root@bc96abf71ef8 src]# gcloud app deploy
@@ -186,7 +188,7 @@ There is a detailed [tutorial](https://developers.google.com/analytics/solutions
If everything went good, you'll get this screen:
![superProxy-deployed](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/03-superProxy-deployed.png)
![superProxy-deployed](/posts/20210103/03-superProxy-deployed.png){: width="1366" height="354"}
### Create Google Analytics Query
@@ -203,37 +205,32 @@ In order to reduce the returned results and reduce the network bandwidth, we add
- **filters**: fill in `ga:pagePath=~^/posts/.*/$;ga:pagePath!@=`.
Among them, `;` means using _logical AND_ to concatenate two rules.
Among them, `;` means using _logical AND_ to concatenate two rules.
If the `site.baseurl` is specified, change the first filtering rule to `ga:pagePath=~^/BASE_URL/posts/.*/$`, where `BASE_URL` is the value of `site.baseurl`.
If the `site.baseurl` is specified, change the first filtering rule to `ga:pagePath=~^/BASE_URL/posts/.*/$`, where `BASE_URL` is the value of `site.baseurl`.
After <kbd>Run Query</kbd>, copy the generated contents of **API Query URI** at the bottom of the page, and fill in the **Encoded URI for the query** of SuperProxy on GAE.
After <kbd>Run Query</kbd>, copy the generated contents of **API Query URI** at the bottom of the page and fill in the **Encoded URI for the query** of SuperProxy on GAE.
After the query is saved on GAE, a **Public Endpoint** (public access address) will be generated, and we will get the query result in JSON format when accessing it. Finally, click <kbd>Enable Endpoint</kbd> in **Public Request Endpoint** to make the query effective, and click <kbd>Start Scheduling</kbd> in **Scheduling** to start the scheduled task.
![superproxy-query](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/04-superproxy-query.png)
![superproxy-query](/posts/20210103/04-superproxy-query.png){: width="1100" height="126"}
## Configure Chirpy to Display Page View
Once all the hard part is done, it is very easy to enable the Page View on Chirpy theme. Your superProxy dashboard should look something like below and you can grab the required values.
![superproxy-dashboard](https://cdn.jsdelivr.net/gh/cotes2020/chirpy-images/posts/20210103/05-superproxy-dashboard.png)
![superproxy-dashboard](/posts/20210103/05-superproxy-dashboard.png){: width="1210" height="694"}
Update the `_config.yml` file of [**Chirpy**][chirpy-homepage] project with the values from your dashboard, to look similar to the following:
```yaml
google_analytics:
id: 'G-XXXXXXXXXX' # Fill with your Google Analytics ID
id: 'G-V6XXXXXXX' # fill in your Google Analytics ID
pv:
# The Google Analytics pageviews switch.
enabled: true
# the next options only valid when `google_analytics.pv` is enabled.
proxy_url: 'https://PROJECT_ID.REGION_ID.r.appspot.com'
proxy_endpoint: 'https://PROJECT_ID.REGION_ID.r.appspot.com/query?id=<ID FROM SUPER PROXY>'
cache: false # pv data local cache, good for the users from GFW area.
cache_path: # the local PV cache data, friendly to visitors from GFW region
```
{: file="_config.yml"}
Now, you should see the Page View enabled on your blog.

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,52 @@
/* ---------- scss placeholder --------- */
%heading {
color: var(--heading-color);
font-weight: 400;
font-family: 'Lato', 'Microsoft Yahei', sans-serif;
}
%section {
#core-wrapper & {
margin-top: 2.5rem;
margin-bottom: 2rem;
}
}
%anchor {
.anchor {
font-size: 1rem;
margin-left: 0.5rem;
}
@media (hover: hover) {
.anchor {
border-bottom: none !important;
visibility: hidden;
opacity: 0;
transition: opacity 0.25s ease-in, visibility 0s ease-in 0.25s;
}
&:hover {
.anchor {
visibility: visible;
opacity: 1;
transition: opacity 0.25s ease-in, visibility 0s ease-in 0s;
}
}
}
}
%anchor-relative {
@extend %anchor;
.anchor {
position: relative;
bottom: 1px;
}
}
%tag-hover {
background: var(--tag-hover);
transition: background 0.35s ease-in-out;
@@ -29,26 +75,24 @@
border-bottom: 1px solid var(--link-underline-color);
}
%clickable-transition {
transition: color 0.35s ease-in-out;
}
%no-cursor {
user-select: none;
}
%no-bottom-border {
border-bottom: none;
}
%heading {
color: var(--heading-color);
font-weight: 400;
font-family: 'Lato', 'Microsoft Yahei', sans-serif;
%cursor-pointer {
cursor: pointer;
}
%section {
#post-wrapper & {
line-height: 1.2;
margin-bottom: 1rem;
}
}
%anchor {
padding-top: 3.5rem;
margin-top: -2.5rem;
%normal-font-style {
font-style: normal;
}
/* ---------- scss mixin --------- */
@@ -57,19 +101,11 @@
text-decoration: none;
}
@mixin sidebar-links($color: rgba(255, 255, 255, 0.5)) {
color: $color;
transition: color 0.35s ease-in-out;
%sidebar-links {
color: rgba(117, 117, 117, 0.9);
user-select: none;
}
@mixin icon-round($diameter) {
border: 1px solid;
border-radius: 50%;
width: $diameter;
height: $diameter;
}
@mixin ml-mr($value) {
margin-left: $value;
margin-right: $value;
@@ -84,28 +120,12 @@
opacity: 0.6;
}
@mixin semi-bold {
font-weight: 600;
}
@mixin label($font-size: 1rem, $font-weight: 600, $color: var(--label-color)) {
color: $color;
font-size: $font-size;
font-weight: $font-weight;
}
@mixin panel-label {
@include label(inherit);
display: block;
line-height: 1.2;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
margin-top: 0;
margin-bottom: 0;
letter-spacing: -0.02em;
}
@mixin align-center {
position: relative;
left: 50%;

View File

@@ -27,24 +27,19 @@ html[mode=dark] {
/* -- Codes Snippet -- */
$code-radius: 6px;
%code-snippet-bg {
background: var(--highlight-bg-color);
}
%code-snippet-radius {
border-radius: 6px;
border-radius: $code-radius;
}
%code-snippet-padding {
padding: 1.5rem;
}
$code-font-size: 0.85rem;
div > pre {
@extend %code-snippet-bg;
@extend %code-snippet-radius;
@extend %code-snippet-padding;
padding-left: 1rem;
padding-right: 1.5rem;
}
.highlighter-rouge {
@@ -65,13 +60,28 @@ div > pre {
}
overflow: auto;
padding-top: 0.5rem;
padding-bottom: 1rem;
pre {
margin-bottom: 0;
font-size: $code-font-size;
line-height: 1.4rem;
word-wrap: normal; /* Fixed Safari overflow-x */
}
table {
td pre {
overflow: visible; /* Fixed iOS safari overflow-x */
word-break: normal; /* Fixed iOS safari linenos code break */
}
}
.lineno {
margin-left: 0.2rem;
padding-right: 0.5rem;
min-width: 2.2rem;
text-align: right;
color: var(--highlight-lineno-color);
border-right: 1px solid var(--highlight-lineno-border-color);
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
@@ -79,24 +89,12 @@ div > pre {
-o-user-select: none;
user-select: none;
}
pre {
margin-bottom: 0;
font-size: $code-font-size;
line-height: 1.4rem;
word-wrap: normal; /* Fixed Safari overflow-x */
}
table {
padding: 0;
border: 0;
td pre {
overflow: visible; /* Fixed iOS safari overflow-x */
word-break: normal; /* Fixed iOS safari linenos code break */
}
}
td {
padding: 0;
border: 0;
/* set the dollar sign to non-selectable */
.gp {
user-select: none;
}
} //.highlight
code {
@@ -112,22 +110,26 @@ code {
background-color: var(--inline-code-bg);
}
@at-root a > &.highlighter-rouge {
a > &.highlighter-rouge {
padding-bottom: 0; // show link's underlinke
color: inherit;
}
@at-root a:hover > &.highlighter-rouge {
a:hover > &.highlighter-rouge {
border-bottom: none;
}
blockquote &.highlighter-rouge {
color: inherit;
}
.highlight > & {
color: transparent;
}
}
td.rouge-code {
padding: 1.5rem 1.5rem 1.5rem 1rem;
@extend %code-snippet-padding;
// Prevent some browser extends from
// changing the URL string of code block.
@@ -144,35 +146,130 @@ div {
&[class^='highlighter-rouge'],
&.language-plaintext.highlighter-rouge,
&.language-console.highlighter-rouge,
&.language-terminal.highlighter-rouge {
&.language-terminal.highlighter-rouge,
&.nolineno {
pre.lineno {
display: none;
}
td.rouge-code {
@extend %code-snippet-padding;
padding-left: 1.5rem;
}
}
}
div[class^='language-']::before {
content: attr(lang);
position: absolute;
right: 2rem;
margin-top: 3px;
font-size: 0.7rem;
font-weight: 600;
color: var(--highlight-lineno-color);
text-transform: uppercase;
.code-header {
@extend %no-cursor;
$code-header-height: 2.25rem;
border-top-left-radius: $code-radius;
border-top-right-radius: $code-radius;
display: flex;
justify-content: space-between;
align-items: center;
height: $code-header-height;
&::before {
$dot-size: 0.75rem;
$dot-margin: 0.5rem;
content: "";
display: inline-block;
margin-left: 1rem;
width: $dot-size;
height: $dot-size;
border-radius: 50%;
background-color: var(--code-header-muted-color);
box-shadow:
($dot-size + $dot-margin) 0 0 var(--code-header-muted-color),
($dot-size + $dot-margin) * 2 0 0 var(--code-header-muted-color);
}
// the label block
span {
// label icon
i {
font-size: 1rem;
margin-right: 0.4rem;
color: var(--code-header-icon-color);
&.small {
font-size: 70%;
}
}
@at-root [file] #{&} > i {
position: relative;
top: 1px; // center the file icon
}
// label text
&::after {
content: attr(label-text);
font-size: 0.85rem;
font-weight: 600;
color: var(--code-header-text-color);
}
}
// clipboard
button {
@extend %cursor-pointer;
border: 1px solid transparent;
border-radius: $code-radius;
height: $code-header-height;
width: $code-header-height;
padding: 0;
background-color: inherit;
i {
color: var(--code-header-icon-color);
}
&[timeout] {
&:hover {
border-color: var(--clipboard-checked-color);
}
i {
color: var(--clipboard-checked-color);
}
}
&:not([timeout]):hover {
background-color: rgba(128, 128, 128, 0.37);
i {
color: white;
}
}
&:focus {
outline: none;
}
}
}
@media (min-width: 768px) {
div[class^='language-']::before {
right: 3.1rem;
}
}
@media all and (max-width: 576px) {
.post-content {
> div[class^='language-'] {
@include ml-mr(-1.25rem);
@media (min-width: 1650px) {
div[class^='language-']::before {
right: 3.5rem;
border-radius: 0;
.highlight {
padding-left: 0.25rem;
}
.code-header {
border-radius: 0;
padding-left: 0.4rem;
padding-right: 0.5rem;
}
}
}
}

View File

@@ -1,22 +1,34 @@
/*
* Mainly scss variables
*/
* The SCSS variables
*/
/* --- ↓ width and height ---- */
/* sidebar */
$tab-height: 3.2rem;
$tab-cursor-height: 1.6rem;
$sidebar-width: 260px !default; // the basic width
$sidebar-width-small: 210px !default; // screen width: >= 850px, <= 1199px (iPad landscape)
$sidebar-width-large: 350px !default; // screen width: >= 1650px
$sidebar-width-small: 210px;
$sidebar-width-medium: 260px;
$sidebar-width-large: 350px;
/* tabs of sidebar */
$topbar-height: 3rem;
$tab-count: 5 !default; // backward compatible (version <= 4.0.2)
$tab-height: 3rem !default;
$tab-cursor-height: 1.6rem !default;
$footer-height: 5rem;
$cursor-width: 2px !default; // the cursor width of the selected tab
$main-content-max-width: 1150px;
/* other framework sizes */
$panel-max-width: 300px;
$topbar-height: 3rem !default;
$post-extend-min-height: 35rem;
$footer-height: 5rem !default;
$footer-height-mobile: 6rem !default; // screen width: <= 576px
$main-content-max-width: 1150px !default;
$panel-max-width: 300px !default;
$bottom-min-height: 35rem !default;
/* syntax highlight */
$code-font-size: 0.85rem !default;

View File

@@ -3,20 +3,6 @@
*/
@mixin dark-syntax {
/* ----- My styles ------ */
--highlight-bg-color: #252525;
--highlighter-rouge-color: #de6b18;
--highlight-lineno-color: #6c6c6d;
--highlight-lineno-border-color: #303435;
--inline-code-bg: #272822;
.highlight {
.gp { color: #818c96; }
}
pre { color: #bfbfbf; } /* override Bootstrap */
kbd { background-color: black; }
/* syntax highlight colors from https://raw.githubusercontent.com/jwarby/pygments-css/master/monokai.css */
.highlight pre { background-color: var(--highlight-bg-color); }
.highlight .hll { background-color: var(--highlight-bg-color); }
@@ -81,4 +67,21 @@
.highlight .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
.highlight .gd { color: #f92672; background-color: #561c08; } /* Generic.Deleted & Diff Deleted */
.highlight .gi { color: #a6e22e; background-color: #0b5858; } /* Generic.Inserted & Diff Inserted */
/* ----- custom styles ------ */
--highlight-bg-color: #252525;
--highlighter-rouge-color: #de6b18;
--highlight-lineno-color: #6c6c6d;
--inline-code-bg: #272822;
--code-header-text-color: #6a6a6a;
--code-header-muted-color: rgb(60 60 60);
--code-header-icon-color: rgb(86 86 86);
--clipboard-checked-color: #2bcc2b;
.highlight {
.gp { color: #818c96; }
}
pre { color: #bfbfbf; } /* override Bootstrap */
}

View File

@@ -3,26 +3,21 @@
*/
@mixin dark-scheme {
/* framework */
--main-wrapper-bg: rgb(27, 27, 30);
/* Framework color */
--body-bg: var(--main-wrapper-bg);
--topbar-wrapper-bg: rgb(39, 40, 43);
--search-wrapper-bg: rgb(34, 34, 39);
--search-icon-color: rgb(100, 102, 105);
--input-focus-border-color: rgb(112, 114, 115);
--mask-bg: rgb(68, 69, 70);
--footer-bg-color: var(--main-wrapper-bg);
/* common color */
--text-color: rgb(175, 176, 177);
--heading-color: #cccccc;
--text-muted-color: rgb(107, 116, 124);
--link-color: rgb(138, 180, 248);
--link-underline-color: rgb(82, 108, 150);
--main-wrapper-bg: rgb(27, 27, 30);
--main-border-color: rgb(44, 45, 45);
--button-bg: rgb(39, 40, 43);
/* Common color */
--text-color: rgb(175, 176, 177);
--text-muted-color: rgb(107, 116, 124);
--heading-color: #cccccc;
--blockquote-border-color: rgb(66, 66, 66);
--blockquote-text-color: rgb(117, 117, 117);
--link-color: rgb(138, 180, 248);
--link-underline-color: rgb(82, 108, 150);
--button-bg: rgb(39, 40, 43);
--btn-border-color: rgb(63, 65, 68);
--btn-backtotop-color: var(--text-color);
--btn-backtotop-border-color: var(--btn-border-color);
@@ -33,21 +28,26 @@
--checkbox-checked-color: var(--link-color);
/* Sidebar */
--nav-cursor-color: rgb(183, 182, 182);
--sidebar-bg: radial-gradient(circle, #242424 0%, #1d1f27 100%);
--sidebar-muted-color: #6d6c6b;
--sidebar-active-color: rgb(255 255 255 / 80%);
--nav-cursor-color: rgb(183, 182, 182);
--sidebar-btn-bg: rgb(117 116 116 / 20%);
/* Top Bar */
/* Topbar */
--topbar-text-color: var(--text-color);
--topbar-wrapper-bg: rgb(39, 40, 43);
--search-wrapper-bg: rgb(34, 34, 39);
--search-wrapper-border-color: rgb(34, 34, 39);
--search-icon-color: rgb(100, 102, 105);
--input-focus-border-color: rgb(112, 114, 115);
/* Home page */
--post-list-text-color: rgb(175, 176, 177);
--btn-patinator-text-color: var(--text-color);
--btn-paginator-hover-color: rgb(64, 65, 66);
--btn-active-bg: rgba(28, 52, 94, 1);
--btn-active-border-color: rgb(66, 94, 138);
--btn-text-color: var(--text-color);
--btn-paginator-border-color: var(--btn-border-color);
--btn-paginator-shadow: var(--main-wrapper-bg);
--btn-text-color: var(--text-color);
--pin-bg: rgb(34 35 37);
--pin-color: inherit;
@@ -65,6 +65,10 @@
--card-bg: rgb(39, 40, 43);
--card-border-color: rgb(53, 53, 60);
--card-box-shadow: var(--main-wrapper-bg);
--preview-img-bg: radial-gradient(circle, rgb(22 22 24) 0%, rgb(32 32 32) 100%);
--kbd-wrap-color: #6a6a6a;
--kbd-text-color: #d3d3d3;
--kbd-bg-color: #242424;
/* tags */
--tag-border: rgb(59, 79, 88);
@@ -75,17 +79,15 @@
/* categories */
--categories-border: rgb(64, 66, 69);
--categories-hover-bg: rgb(73, 75, 76);
--categories-icon-hover-color: white;
/* archives */
--timeline-node-bg: rgb(150, 152, 156);
--timeline-color: rgb(63, 65, 68);
--timeline-year-dot-color: var(--timeline-color);
/* Footer */
--footer-link: rgb(171, 171, 171);
.post-content img {
filter: brightness(90%);
.post img[data-src] {
filter: brightness(95%);
}
hr {
@@ -112,11 +114,13 @@
.card-header {
background-color: var(--card-header-bg);
}
.list-group-item {
border-left: none;
border-right: none;
padding-left: 2rem;
border-color: var(--categories-border);
&:last-child {
border-bottom-color: var(--card-bg);
}
@@ -124,13 +128,21 @@
}
#archives li:nth-child(odd) {
background-image: linear-gradient(
to left,
rgb(26, 26, 30),
rgb(39, 39, 45),
rgb(39, 39, 45),
rgb(39, 39, 45),
rgb(26, 26, 30));
background-image:
linear-gradient(
to left,
rgb(26, 26, 30),
rgb(39, 39, 45),
rgb(39, 39, 45),
rgb(39, 39, 45),
rgb(26, 26, 30)
);
}
color-scheme: dark;
#disqus_thread {
color-scheme: none;
}
} // dark-scheme

View File

@@ -68,8 +68,12 @@
/* --- custom light colors --- */
--highlight-bg-color: #f7f7f7;
--highlighter-rouge-color: #505050;
--highlighter-rouge-color: #2f2f2f;
--highlight-lineno-color: #c2c6cc;
--highlight-lineno-border-color: #e9ecef;
--inline-code-bg: #f3f3f3;
--code-header-text-color: #a3a3b1;
--code-header-muted-color: #ebebeb;
--code-header-icon-color: #d1d1d1;
--clipboard-checked-color: #43c743;
} // light-syntax

View File

@@ -3,22 +3,22 @@
*/
@mixin light-scheme {
/* Common */
/* Framework color */
--body-bg: #fafafa;
--mask-bg: #c1c3c5;
--main-wrapper-bg: white;
--main-border-color: #f3f3f3;
--btn-border-color: #e9ecef;
--text-color: #4a4a4a;
/* Common color */
--text-color: #34343c;
--text-muted-color: gray;
--heading-color: black;
--blockquote-border-color: #eee;
--blockquote-text-color: #9a9a9a;
--link-color: #2a408e;
--link-underline-color: #dee2e6;
--text-muted-color: gray;
--tb-odd-bg: #fbfcfd;
--tb-border-color: #eaeaea;
--button-bg: #fff;
--btn-border-color: #e9ecef;
--btn-backtotop-color: #686868;
--btn-backtotop-border-color: #f1f1f1;
--btn-box-shadow: #eaeaea;
@@ -26,16 +26,17 @@
--checkbox-checked-color: #07a8f7;
/* Sidebar */
--sidebar-bg: radial-gradient(
circle,
rgba(42, 30, 107, 1) 0%,
rgba(35, 37, 46, 1) 100%);
--nav-cursor-color: #fcfcfc;
--sidebar-bg: #eeeeee;
--sidebar-muted-color: #a2a19f;
--sidebar-active-color: #424242;
--nav-cursor-color: #757575;
--sidebar-btn-bg: white;
/* Topbar */
--topbar-wrapper-bg: white;
--topbar-text-color: rgb(78, 78, 78);
--search-wrapper-bg: #f5f5f5;
--topbar-wrapper-bg: white;
--search-wrapper-bg: rgb(245 245 245 / 50%);
--search-wrapper-border-color: rgb(245 245 245);
--search-tag-bg: #f8f9fa;
--search-icon-color: #c2c6cc;
--input-focus-border-color: var(--btn-border-color);
@@ -43,12 +44,9 @@
/* Home page */
--post-list-text-color: dimgray;
--btn-patinator-text-color: #555555;
--btn-paginator-hover-color: #e9ecef;
--btn-active-bg: #2a408e;
--btn-active-border-color: #007bff;
--btn-text-color: #f8f8f8;
--btn-paginator-border-color: #f1f1f1;
--btn-paginator-shadow: #4b92d2;
--btn-paginator-hover-color: var(--sidebar-bg);
--btn-paginator-border-color: var(--sidebar-bg);
--btn-text-color: #676666;
--pin-bg: #f5f5f5;
--pin-color: #999fa4;
@@ -58,20 +56,26 @@
--card-box-shadow: rgba(234, 234, 234, 0.7686274509803922);
--label-color: #616161;
--relate-post-date: rgba(30, 55, 70, 0.4);
--footnote-target-bg: lightcyan;
--tag-bg: rgba(0, 0, 0, 0.075);
--tag-border: #dee2e6;
--tag-shadow: var(--btn-border-color);
--tag-hover: rgb(222, 226, 230);
--categories-hover-bg: var(--btn-border-color);
--tb-odd-bg: #fbfcfd;
--tb-border-color: #eaeaea;
--dash-color: silver;
--preview-img-bg: radial-gradient(circle, rgb(255 255 255) 0%, rgb(249 249 249) 100%);
--kbd-wrap-color: #bdbdbd;
--kbd-text-color: var(--text-color);
--kbd-bg-color: white;
/* Categories */
--categories-hover-bg: var(--btn-border-color);
--categories-icon-hover-color: darkslategray;
/* Archive */
--timeline-color: rgba(0, 0, 0, 0.075);
--timeline-node-bg: #c2c6cc;
--timeline-year-dot-color: #ffffff;
/* Footer */
--footer-bg-color: #ffffff;
--footnote-target-bg: lightcyan;
--footer-link: #424242;
} // light-scheme

View File

@@ -1,7 +1,7 @@
/*!
* The styles for Jekyll theme Chirpy
*
* Chirpy v3.2.2 (https://github.com/cotes2020/jekyll-theme-chirpy)
* Chirpy v5.0.1 (https://github.com/cotes2020/jekyll-theme-chirpy)
* © 2019 Cotes Chung
* MIT Licensed
*/
@@ -12,6 +12,7 @@
"addon/module",
"addon/variables",
"variables-hook",
"addon/syntax",
"addon/commons",

View File

@@ -41,6 +41,7 @@
&:not(:first-child) {
position: relative;
left: 4px;
&::after {
left: 67px;
}
@@ -98,6 +99,7 @@
.date {
white-space: nowrap;
display: inline-block;
&.month {
width: 1.4rem;
text-align: center;
@@ -120,6 +122,7 @@
z-index: 1;
}
}
&.day {
font-size: 85%;
font-family: 'Lato', sans-serif;
@@ -127,7 +130,7 @@
margin-right: -2px;
width: 1.2rem;
position: relative;
left: -.15rem;
left: -0.15rem;
}
} // #archives .date
@@ -136,6 +139,7 @@
@media all and (max-width: 576px) {
#archives {
margin-top: -1rem;
ul {
letter-spacing: 0;
}

View File

@@ -8,24 +8,22 @@
.categories {
margin-bottom: 2rem;
.card-header {
padding-right: 12px;
}
i {
&.far,
&.fas {
font-size: 86%; // fontawesome icons
}
@extend %category-icon-color;
font-size: 86%; // fontawesome icons
}
.list-group-item {
border-left: none;
border-right: none;
padding-left: 2rem;
> i {
@extend %category-icon-color;
}
&:first-child {
border-top-left-radius: 0;
border-top-right-radius: 0;
@@ -33,10 +31,6 @@
}
.card-header > span > i:first-child {
@extend %category-icon-color;
}
} // .categories
.category-trigger {
@@ -45,11 +39,18 @@
border-radius: 50%;
text-align: center;
color: #6c757d !important;
> i.fas {
&:hover {
i {
color: var(--categories-icon-hover-color);
}
}
i {
position: relative;
height: 0.7rem;
width: 1rem;
transition: 300ms ease all;
transition: transform 300ms ease;
}
}

View File

@@ -3,7 +3,7 @@
*/
.dash {
margin: 0 .5rem .6rem .5rem;
margin: 0 0.5rem 0.6rem 0.5rem;
border-bottom: 2px dotted var(--dash-color);
}
@@ -60,8 +60,9 @@
#page-tag {
ul > li {
&::before {
margin: 0 .5rem;
margin: 0 0.5rem;
}
> a {
white-space: nowrap;
overflow: hidden;

View File

@@ -3,55 +3,52 @@
*/
.pagination {
font-size: 1rem;
color: var(--btn-patinator-text-color);
font-family: 'Lato', sans-serif;
a:hover {
text-decoration: none;
}
.page-item {
.page-link {
color: var(--btn-patinator-text-color);
color: inherit;
width: 2.5rem;
height: 2.5rem;
padding: 0;
text-align: center;
display: -webkit-box;
display: flex;
-webkit-box-pack: center;
justify-content: center;
-webkit-box-align: center;
align-items: center;
border-radius: 50%;
border: 1px solid var(--btn-paginator-border-color);
font-family: 'Lato', sans-serif;
background-color: var(--button-bg);
&:hover {
background-color: var(--btn-paginator-hover-color);
}
}
&.active {
.page-link {
background-color: var(--btn-active-bg);
border-color: var(--btn-active-border-color);
box-shadow: 0 0 8px 0 var(--btn-paginator-shadow) !important;
background-color: var(--btn-paginator-hover-color);
color: var(--btn-text-color);
}
}
&.disabled {
cursor: not-allowed;
.page-link {
color: rgba(108, 117, 125, 0.57);
border-color: var(--btn-paginator-border-color);
background-color: var(--button-bg);
}
}
&:first-child .page-link,
&:last-child .page-link {
border-radius: 50%;
}
&:not(:last-child) {
margin-right: 0.7rem;
}
} // .page-item
} // .pagination
@@ -77,9 +74,14 @@
.post-meta {
i {
font-size: 0.73rem;
&:not(:first-child) {
margin-left: 1.2rem;
}
}
span:not(:last-child) {
margin-right: 1.2rem;
em {
@extend %normal-font-style;
}
}
@@ -87,6 +89,7 @@
margin-top: 0.6rem;
margin-bottom: 0.6rem;
color: var(--post-list-text-color);
> p {
/* Make preview shorter on the homepage */
margin: 0;
@@ -104,27 +107,35 @@
padding-left: 3px;
color: var(--pin-color);
}
> span {
display: none;
}
}
} // .post-preview
} // #post-list
/* Hide SideBar and TOC */
@media all and (max-width: 830px) {
.pagination {
justify-content: center;
justify-content: space-evenly;
.page-item {
&:not(:first-child):not(:last-child) {
display: none;
}
}
}
}
/* Sidebar is visible */
@media all and (min-width: 831px) {
#post-list {
margin-top: 1.5rem;
.post-preview .post-meta {
.pin {
background: var(--pin-bg);
@@ -144,11 +155,24 @@
.pagination {
font-size: 0.85rem;
.page-item .page-link {
width: 2.2rem;
height: 2.2rem;
.page-item {
&:not(:last-child) {
margin-right: 0.7rem;
}
.page-link {
width: 2rem;
height: 2rem;
}
}
}
.page-index {
display: none;
}
} // .pagination
}

View File

@@ -16,39 +16,37 @@
border-color: var(--btn-border-color);
}
@mixin dot($pl: 0.2rem, $pr: 0.4rem) {
@mixin dot($pl: 0.25rem, $pr: 0.25rem) {
content: "\2022";
color: rgba(158, 158, 158, 0.8);
padding-left: $pl;
padding-right: $pr;
}
.timeago::before {
content: attr(prefix);
%text-color {
color: var(--text-color);
}
#post-wrapper .post-meta {
> div:nth-child(2) {
> span:not(:first-child)::before {
@include dot;
h1 + .post-meta {
span + span::before {
@include dot;
}
em {
@extend %text-color;
a {
@extend %text-color;
}
}
#pv::after {
content: " views";
}
.readtime::after {
content: " read";
}
}
.post-content {
.preview-img {
@include align-center;
img.preview-img {
margin-top: 3.75rem;
margin-bottom: 0;
border-radius: 6px;
margin-top: 0;
margin-bottom: 2.5rem !important;
&.bg[data-loaded=true] {
background: var(--preview-img-bg);
}
}
@@ -56,6 +54,10 @@
margin-top: 6rem;
border-bottom: 1px double var(--main-border-color);
font-size: 0.85rem;
.post-meta a {
@extend %link-underline;
}
}
.post-tags {
@@ -121,7 +123,7 @@
white-space: normal;
}
} // .post-navigation
} /* .post-navigation */
@keyframes fade-up {
from {
@@ -143,18 +145,23 @@
top: 4rem;
transition: top 0.2s ease-in-out;
animation: fade-up 0.8s;
&.topbar-down {
top: 6rem;
}
> span {
@include panel-label;
}
}
#toc li > a {
line-height: 1rem;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
#toc li a {
font-size: 0.8rem;
&.nav-link:not(.active) {
color: inherit;
}
}
nav[data-toggle=toc] {
.nav {
.nav > li > a.active {
font-weight: 600 !important;
}
}
}
/* --- Related Posts --- */
@@ -163,6 +170,11 @@
> h3 {
@include label(1.1rem, 600);
}
em {
@extend %normal-font-style;
}
.card {
border-color: var(--card-border-color);
background-color: var(--card-bg);
@@ -170,9 +182,11 @@
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
h3 {
color: var(--text-color);
@extend %text-color;
}
&:hover {
-webkit-transform: translate3d(0, -3px, 0);
transform: translate3d(0, -3px, 0);
@@ -201,6 +215,7 @@
ul {
list-style-type: none;
padding-inline-start: 1.5rem;
> li::before {
background: #c2c9d4;
width: 5px;
@@ -215,11 +230,17 @@
}
}
#post-extend-wrapper {
#tail-wrapper {
min-height: 2rem;
#disqus_thread {
> div:last-of-type {
margin-bottom: 2rem;
}
#disqus_thread {
min-height: 8.5rem;
}
}
.post-tail-bottom a {
@@ -236,45 +257,57 @@
.share-icons {
font-size: 1.2rem;
a {
&:not(:last-child) {
margin-right: 0.25rem;
}
&:hover {
text-decoration: none;
> i {
@extend %btn-share-hovor;
}
}
}
> i {
padding-top: 0.35rem;
position: relative;
bottom: 1px;
@extend %cursor-pointer;
&:hover {
@extend %btn-share-hovor;
}
}
.fab {
&.fa-twitter {
@include btn-sharing-color(rgba(29, 161, 242, 1));
}
&.fa-facebook-square {
@include btn-sharing-color(rgb(66, 95, 156));
}
&.fa-telegram {
@include btn-sharing-color(rgb(39, 159, 217));
}
&.fa-weibo {
@include btn-sharing-color(rgb(229, 20, 43));
}
}
} // .share-icons
} /* .share-icons */
.fas.fa-link {
@include btn-sharing-color(rgb(171, 171, 171));
}
} // .share-wrapper
} /* .share-wrapper */
.share-label {
@include label(inherit, 400, inherit);
@@ -286,8 +319,10 @@
.license-wrapper {
line-height: 1.2rem;
> a {
font-weight: 600;
color: var(--text-color);
&:hover {
@extend %link-hover;
}
@@ -296,27 +331,23 @@
span:last-child {
font-size: 0.85rem;
}
} // .license-wrapper
} /* .license-wrapper */
@media all and (max-width: 576px) {
.preview-img[data-src] {
margin-top: 2.2rem;
}
.post-tail-bottom {
-ms-flex-wrap: wrap-reverse !important;
flex-wrap: wrap-reverse !important;
>div:first-child {
> div:first-child {
width: 100%;
margin-top: 1rem;
}
}
.post-content > div[class^='language-'] {
@include ml-mr(-1.25rem);
border-radius: 0;
&::before { // the lang badge
right: 1rem;
}
}
}
@media all and (max-width: 768px) {
@@ -325,28 +356,17 @@
}
}
@media all and (min-width: 768px) {
#post-wrapper {
.post-meta {
>div:not(:first-child)::before {
@include dot(0.5rem, 0.2rem);
}
&.flex-column {
-webkit-box-orient: horizontal !important;
-webkit-box-direction: normal !important;
-ms-flex-direction: row !important;
flex-direction: row !important;
}
}
} // .post
}
/* Hide SideBar and TOC */
@media all and (max-width: 830px) {
@media all and (max-width: 849px) {
.post-navigation {
padding-left: 0;
padding-right: 0;
margin-left: -.5rem;
margin-right: -.5rem;
margin-left: -0.5rem;
margin-right: -0.5rem;
}
.preview-img[data-src] {
max-width: 100vw;
border-radius: 0;
}
}

View File

@@ -10,6 +10,7 @@
letter-spacing: 0;
border: 1px solid var(--tag-border) !important;
box-shadow: 0 0 3px 0 var(--tag-shadow);
span {
margin-left: 0.6em;
font-size: 0.7em;

View File

@@ -0,0 +1,3 @@
/*
Appending custom SCSS variables will override the default ones in `_sass/addon/variables.scsss`
*/

View File

@@ -1,6 +1,6 @@
---
title: About
icon: fas fa-info
icon: fas fa-info-circle
order: 4
---

Some files were not shown because too many files have changed in this diff Show More