This is a fork of jekyll-theme-chirpy that has been modified to include a custom tabbed container plugin, custom gallery slideshow plugin, custom image proxy (e.g. for Twitter links), custom plugin to fix malformed Markdown links (originally generated by Enveloppe), auto-generates CNAME and .nojekyll files during build and deployment, custom "Important" prompt, and more.
- Jekyll
- Liquid
- Markdown
- Ruby
- HTML
- SCSS
- JavaScript
- GitHub Actions
- Obsidian
- Enveloppe
- Giscus
- Cloudflare
sh tools/run.shTip
Use this command if the previous one doesn't work
bundle exec jekyll serve --incrementalTo 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
Ensure:
- Repository is public
- Giscus app is installed
- Discussions feature is enabled for repository
Install by going to Giscus and filling out the form. 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
- 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/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 STEPS: 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>
- 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)
Full credit for jekyll-theme-chirpy goes to cotes2020.
Check out the theme's docs for more information and the theme's license for the license.