This is a fork of jekyll-theme-chirpy that has been heavily modified to include a graph view plugin, tabbed container plugin, gallery slideshow plugin, link preview, image proxy (e.g. for Twitter links), Jekyll plugin to fix malformed Markdown links, auto-generates CNAME and .nojekyll files during build and deployment, custom "Important" prompt, custom details styling, and more.
Tip
Use this command if the shell script doesn't work
bundle exec jekyll serve --incrementalStart dev environment (aka run local server)
sh tools/run.shsh tools/init.shTo keep fork up-to-date with original repository (i.e. Chirpy)
- Link the upstream (i.e. original) repository to fork
git remote add upstream https://github.com/cotes2020/jekyll-theme-chirpy.git
Tip
Use this command if you've already linked the upstream repository and want to re-link it
git remote set-url upstream https://github.com/cotes2020/jekyll-theme-chirpy.git- Confirm the remote URL with either command
-
Command #1
-
Input:
git remote show
-
Output should look similar to:
origin upstream
-
-
Command #2
-
Input:
git remote -v
-
Output should look similar to:
origin https://github.com/lynkos/blog.git (fetch) origin https://github.com/lynkos/blog.git (push) upstream https://github.com/cotes2020/jekyll-theme-chirpy.git (fetch) upstream https://github.com/cotes2020/jekyll-theme-chirpy.git (push)
-
-
Fetch latest changes from upstream repository
git fetch upstream master
-
Switch to
masterbranch (so it's recognized)git checkout master
-
Switch to the branch you want to sync
git checkout main
-
Merge changes from upstream into local branch
git merge upstream/main
-
Push changes to your fork
git push origin main
Install by going to Giscus and filling out the form. For it to work, these requirements must be met:
- Repository is public
- Giscus app is installed
- Discussions feature is enabled for repository
Example code with my configuration:
<script src="https://giscus.app/client.js"
data-repo="<GITHUB_USERNAME>/<REPO>"
data-repo-id="<REPO_ID>"
data-category="Announcements"
data-category-id="<CATEGORY_ID>"
data-mapping="pathname"
data-strict="0"
data-reactions-enabled="1"
data-emit-metadata="0"
data-input-position="top"
data-theme="preferred_color_scheme"
data-lang="en"
data-loading="lazy"
crossorigin="anonymous"
async>
</script>-
Open Settings (⌘ + ,)
-
Go to Community plugins tab
-
Turn off Restricted mode to enable community plugins
-
Click Browse, which is next to Community plugins
-
Enter
Enveloppein the searchbar -
Click on Enveloppe, then click Install (note: I'm using Version
7.6.3) -
Once Enveloppe's installed, go to its Settings
-
Copy my Enveloppe settings:
{ "github": { "branch": "main", "automaticallyMergePR": true, "dryRun": { "enable": false, "folderName": "enveloppe" }, "api": { "tiersForApi": "Github Free/Pro/Team (default)", "hostname": "" }, "workflow": { "commitMessage": "[OBSIDIAN] Merge", "name": "" }, "verifiedRepo": true }, "upload": { "behavior": "fixed", "defaultName": "_posts", "rootFolder": "", "yamlFolderKey": "", "frontmatterTitle": { "enable": true, "key": "filename" }, "replaceTitle": [ { "regex": "/\\s+/", "replacement": "-", "type": "title" } ], "replacePath": [], "autoclean": { "includeAttachments": true, "enable": false, "excluded": [] }, "folderNote": { "enable": false, "rename": "index.md", "addTitle": { "enable": false, "key": "title" } }, "metadataExtractorPath": "" }, "conversion": { "hardbreak": false, "dataview": true, "censorText": [], "tags": { "inline": false, "exclude": [], "fields": [] }, "links": { "internal": true, "unshared": true, "wiki": true, "slugify": "strict", "unlink": true, "relativePath": true, "textPrefix": "/" } }, "embed": { "attachments": true, "overrideAttachments": [], "keySendFile": [], "notes": false, "folder": "assets/img/obsidian", "convertEmbedToLinks": "keep", "charConvert": "->", "unHandledObsidianExt": [], "sendSimpleLinks": true, "forcePush": true, "useObsidianFolder": false }, "plugin": { "shareKey": "share", "excludedFolder": [ "templates" ], "copyLink": { "enable": false, "links": "", "removePart": [], "addCmd": false, "transform": { "toUri": true, "slugify": "lower", "applyRegex": [] } }, "setFrontmatterKey": "Set" } } -
Click Import settings and paste the copied
enveloppe.json(from the previous step) where it saysPaste configuration here..., then click Save -
Under GitHub config, enter your GitHub username, Repository name, and — if your main branch is not named
main— Main branch name -
Generate a fine-grained personal access token for your GitHub repository in order to give Enveloppe necessary permissions to work by going to your GitHub settings
-
Scroll down and click Developer settings
-
Click Personal access tokens, click Fine-grained tokens, then click Generate new token
-
Enter a descriptive Token name (e.g.
Enveloppe (Obsidian)) and Description (e.g.Enveloppe (Obsidian Vault → GitHub Repo)) -
Choose your GitHub account as Resource owner
-
Select No expiration for Expiration
-
Under Repository access, click Only select repositories then click Select repositories and select the GitHub repository for your Jekyll blog (e.g.
lynkos/blog) -
Click Repository permissions under Permissions
-
Always choose the minimal permissions necessary, so all options should be set to Access: No access, with the exception of the following:
Permission Access Reason Contents Read and write Create branch Metadata Read-only Mandatory Pull requests Read and write Create and merge pull requests Workflows Read and write Create/update file -
Click Generate token
-
Copy the generated GitHub personal access token; it should start with
github_followed by a long, random string of alphanumeric characters and underscores -
Back in Enveloppe settings, paste it in the GitHub token area
A custom Cloudflare Worker hotlinks images from sites that may restrict it; this way I can embed images from Twitter/X. Custom Ruby plugin _plugins/gallery.rb automatically prepends Twitter/X URLs within a gallery (i.e. {% gallery %} ... {% endgallery %}) with the value of worker_base_url. Additional sites will be added as needed. Currently only supports Twitter/X.
- Sign up and/or login to Cloudflare
- Go to your dashboard
- In the left pane, click Compute (Workers), then Workers & Pages
- Click the blue Create application button in the upper-right corner
- In the Workers tab, click the blue Get Started button to the right of Start with Hello World!
- Name the worker
img-proxy - Click Deploy
- You should be redirected to a page that says Success! Your project is deployed to Region: ...
- Click the Edit Code button; you can also access this page later by going to Compute (Workers) > Workers & Pages, clicking the worker (i.e.
img-proxy), then clicking the small icon </> in the upper-right corner - This should open the Cloudflare Workers IDE; replace the default code in
worker.jswith the following code:export default { /** * @param {{ url: string | URL; }} request */ async fetch(request) { const url = new URL(request.url); const target = url.searchParams.get("url"); // i.e. ?url=https://pbs.twimg.com/media/... if (!target) { return new Response("Missing ?url= param", { status: 400 }); } try { const resp = await fetch(target, { headers: { "User-Agent": "Mozilla/5.0" } }); const headers = new Headers(resp.headers); headers.set("Access-Control-Allow-Origin", "*"); return new Response(await resp.arrayBuffer(), { status: resp.status, headers }); } catch (err) { return new Response("Fetch error: " + err.message, { status: 502 }); } } };
Tip
Test the worker in the Preview pane by adding ?url= and the link to an image on Twitter (e.g. https://pbs.twimg.com/media/GzPhoaKWoAA16uA?format=jpg&name=medium) following AFTER your worker's URL (i.e. https://img-proxy.<YOUR_DOMAIN_NAME>.workers.dev/) in the input field
So, in this example, the full URL is: https://img-proxy.<YOUR_DOMAIN_NAME>.workers.dev/?url=https://pbs.twimg.com/media/GzPhoaKWoAA16uA?format=jpg&name=medium
Click the Reload button (circular arrow icon) to the right of the input field to test it; if successful, you should see the image in the Preview pane
- Click Deploy in the upper-right corner
- You can now use this worker as an image proxy by using the following URL format:
where
https://img-proxy.<YOUR_DOMAIN_NAME>.workers.dev/?url=<IMAGE_URL>
<YOUR_DOMAIN_NAME>is your Cloudflare domain (e.g.example.com) and<IMAGE_URL>is the full URL of the image you want to hotlink (e.g.https://pbs.twimg.com/media/GzPhoaKWoAA16uA?format=jpg&name=medium)
OPTIONAL: USE CUSTOM DOMAIN (e.g. img-proxy.<YOUR_ROOT_DOMAIN>)
- In the left pane, click DNS, then Records
- Click the blue + Add record button, then add a new record with the following details:
- Type:
CNAME - Name:
img-proxy(or whatever subdomain you want to use) - IPv4 address:
workers.dev - Proxy status:
Proxiedaka Enabled (orange cloud icon) - TTL:
Auto - Comment:
Map img-proxy worker (at img-proxy.<YOUR_DOMAIN_NAME>.workers.dev) to img-proxy.<YOUR_ROOT_DOMAIN>
- Type:
- Click Save
- Click Workers Routes in the left pane, then click the blue Add route button in the HTTP Routes section
- In the Route field, enter
img-proxy.<YOUR_ROOT_DOMAIN>/* - Under Worker, select
img-proxyworker (or whatever you named it) from the dropdown - Click Save
- You can now use the custom domain for your image proxy at
https://img-proxy.<YOUR_ROOT_DOMAIN>/?url=<IMAGE_URL>(e.g.https://img-proxy.example.com/?url=https://pbs.twimg.com/media/GzPhoaKWoAA16uA?format=jpg&name=medium)
Run this command after making any changes to files in _javascript/ directory to update (i.e. rebuild JavaScript bundle):
npm run build:jsSee package.json for more scripts and details.
Continue reading if you want to create a pull request in jekyll-theme-chirpy with only a subset of your commits. This is useful if you want to add a feature to upstream without committing all your changes.
- If you haven't already, complete the steps in Sync Fork with Upstream section
- Create a new branch, e.g.
BRANCH_NAMEgit checkout -b BRANCH_NAME upstream/master
- Cherry pick the commit(s) you want to include in the PR
git cherry-pick COMMIT_HASH
- Push your branch
git push origin BRANCH_NAME
- If successful, the terminal should output something similar to this:
Enumerating objects: 111, done. Counting objects: 100% (83/83), done. Delta compression using up to 16 threads Compressing objects: 100% (50/50), done. Writing objects: 100% (51/51), 8.50 KiB | 1.70 MiB/s, done. Total 51 (delta 36), reused 0 (delta 0), pack-reused 0 (from 0) remote: Resolving deltas: 100% (36/36), completed with 26 local objects. remote: remote: Create a pull request for 'BRANCH_NAME' on GitHub by visiting: remote: https://github.com/GITHUB_USERNAME/REPOSITORY_NAME/pull/new/BRANCH_NAME remote: To https://github.com/GITHUB_USERNAME/REPOSITORY_NAME.git * [new branch] BRANCH_NAME -> BRANCH_NAME - Go to the originally forked repository, i.e.
jekyll-theme-chirpy - Click the New pull request button
- Complete the pull request template accordingly
- Click the Create pull request button
To add a preview image to a post, add the following front matter to the top of the post's Markdown file:
image:
path: /path/to/image.png
lqip: base64-encoded-lqip
alt: Image caption and alt textTo generate a base64-encoded LQIP for the lqip field:
- Visit lqip generator
- Input your preview image
- Customize the options as needed; here are my recommendations:
- Placeholder Size:
Small - Quality:
60 - Blur Amount:
5px
- Click Generate LQIP
- Click Download to save the generated image
- Visit Image to Base64 (alternatively, you can use another base64 encoder)
- Under Datatype, select Local File
- Under Local File, click Browse... and select the downloaded LQIP
- Under Output Format, select Data URI -- data:content/type;base64
- Click Encode image to Base64 and copy the generated base64 string
- Paste the base64 string in the
lqipfield of the front matter
If you want to confirm that the base64 string works, you can either:
- Paste it in your browser's address bar, then click Enter
- Visit Base64 Image Viewer and paste the base64 string in the input field below Base64 Image String
Full credit for jekyll-theme-chirpy goes to cotes2020, aka Cotes Chung.
For more information, check out the Wiki docs and original license.