Jekyll tips for github pages
Installation
Here are the steps you can follow to generate myblog
gem install jekyll
jekyll new myblog
cd myblog
git init .
git add .
git commit -m "Initial jekyll new myblog"
Add usefull gems
cat >> Gemfile << 'HERE_DOC'
gem 'jekyll-seo-tag'
gem 'jekyll-sitemap'
HERE_DOR
Live reload is now built in (no need for guard-livereload
). You just need to
run with option jekyll serve --livereload
For livereload you need to install Chrome plugin enable it and activate by clicking on icon when you open a page. There is also plugin for firefox https://addons.mozilla.org/en-US/firefox/addon/livereload-web-extension/ You can use javascript version.
Custom domain
If your repo is the only or is primary, you can use
Do not need to rename if you want custom domain, you can enable it from settings https://github.com/duleorlovic/trk.in.rs/settings or you can just create CNAME file manually since that is the same
git chechout -t origin/gh-pages
echo "www.trk.in.rs" > CNAME
You need to configure your domain name provider to point to your github
respository with CNAME
record
to point to {username}.github.io
, for example CNAME duleorlovic.github.io
.
Check when it is updated, usually in one hour
# note that second column is TTL time to live in secods
dig +nostats +nocomments +nocmd www.trk.in.rs
;www.trk.in.rs. IN A
www.trk.in.rs. 3600 IN CNAME kulakajak.github.io.
kulakajak.github.io. 3600 IN A 185.199.111.153
kulakajak.github.io. 3600 IN A 185.199.110.153
Use this only for subdomains (www.trk.in.rs, blog.trk.in.rs) and not for apex domain. Adding CNAME record to the root of your domain will disable MX and TXT records. If you need to apex domain (and not to destroy other records) you can try with ANAME record (not supported in loopia), or use Cloudflare flattening
Default duleorlovic.github.io
is serverd under HTTPS, but custom domain is
serverd under HTTP. To enable HTTPS for custom domains you can try
cloudflare but recently, all github pages are
enypted with free https://letsencrypt.org/ certificate.
Do not leave dns record to github without domain validation
What happened to me is that I leave CNAME record openfoodnetwork.trk.in.rs to point to github kulakajak.github.io but did not use custom domain on github pages and attacker used same domain to serve his website. I found because I received email that attacker added account on google search console for my domain
New owner for http://openfoodnetwork.trk.in.rs/
To owner of trk.in.rs,
Google has identified that [email protected] has been added as an owner of http://openfoodnetwork.trk.in.rs/.
openfoodnetwork.trk.in.rs
Cloudflare
Adding CNAME on root domain is possible, it is calling CNAME Flattening.
You can use cloudflare and heroku to catch all subdomains to same herokuapp
https://devcenter.heroku.com/articles/custom-domains#add-a-wildcard-domain
https://support.cloudflare.com/hc/en-us/articles/360017421192%20#CloudflareDNSFAQ-DoesCloudflaresupportwildcardDNSentries
Add *.myapp.com
(same as it is normal subdomain) to heroku, and use that CNAME
value on for cloudflare.
Note that only paid plans will use Cloudflare CDN… this subdomains will go directly to herokuapp. For example if you add root and www and wildcard subdomain you will see that root and www goes to Cloudflare IP addresses.
dig +noall +answer move-index.org
move-index.org. 300 IN A 104.28.14.249
move-index.org. 300 IN A 104.28.15.249
dig +noall +answer www.move-index.org
www.move-index.org. 300 IN A 104.28.14.249
www.move-index.org. 300 IN A 104.28.15.249
dig +noall +answer asd.move-index.org
asd.move-index.org. 300 IN CNAME vertical-radish-wbe8hucc40fc2vqud0b15mzk.herokudns.com.
vertical-radish-wbe8hucc40fc2vqud0b15mzk.herokudns.com. 60 IN A 52.2.175.150
vertical-radish-wbe8hucc40fc2vqud0b15mzk.herokudns.com. 60 IN A 52.21.103.149
Redirection in cloudflare can be configured with Bulk Redirect Lists than you
can find on main account page menu as Bulk Redirects
.
First click on Create Bulk Redirect List, from uplate.trk.in.rs/
to
https://docs.google.com/1234
and than Create Redirect Rule and choose the list.
You also need to create a subdomain uplate
A record 192.0.2.1
Proxied.
IP address is not important, but keep 192.0.2.1 for simplicity.
Use bulk redirects also for redirection from root to subdomain https://developers.cloudflare.com/fundamentals/get-started/basic-tasks/manage-subdomains/
Just add subdomain @
root, A record with value 192.0.2.1
Proxied.
Then add Bulk redirection list to redirect from trk.in.rs
to
https://www.trk.in.rs
.
than go to Bulk redirects and Create Bulk Redirect using this list
Cloudfront
dig +nostats +nocomments +nocmd projektor.trk.in.rs
;projektor.trk.in.rs. IN A
projektor.trk.in.rs. 3405 IN CNAME d1ub4fmsp3scvp.cloudfront.net.
d1ub4fmsp3scvp.cloudfront.net. 47 IN A 13.32.22.82
Loopia
If you want redirection from non www to www, than use Forwatd -> Url redirect (301 or 302) but uncheck “Synchronize the domain and subdomain www”
Jekyll on github
Easiest way to start a blog on github it to fork
https://github.com/barryclark/jekyll-now and rename it to
duleorlovic.github.io
and start editing using http://prose.io/. There is
nothing special there, just simple jekyll project, with
_includes for
discuss, analytics, meta and uses gems: jekyll-sitemap
which github supports.
It does not use theme. It is very similar to default jekyll theme
minima
Jekyll default template minima can be overriden with
bundle show minima
# ~/.rvm/gems/ruby-2.5.1/gems/minima-2.5.0
mkdir _includes
cp `bundle show minima`/_includes/@(footer|header|head).html _includes/
git add .
git commit -am 'cp `bundle show minima`/_includes/@(footer|header|head).html _includes/'
Travis
This gist explain what
to do. In additional you need to use bundle install && bundle exec jekyll build
-d out
as build command, use proper ruby supported by travis rvm: - 2.2
,
exclude vendor
from jekyll, and note the label string that travis
cli
generate when you encrypt.
You need to generate keys which Travis will use to deploy. You need to write to
deploy_key
and to not label from travis cli.
ssh-keygen -t rsa -b 4096 -C "[email protected]" deploy_key
travis encrypt-file deploy_key
git add deploy_key.enc
mv deploy_key deploy_key.pub ~/.ssh/
cat >> deploy.sh << HERE_DOC
#!/bin/bash
set -e # Exit with nonzero exit code if anything fails
SOURCE_BRANCH="master"
TARGET_BRANCH="gh-pages"
function doCompile {
bundle install
bundle exec jekyll build -d out
}
# Pull requests and commits to other branches shouldn't try to deploy, just build to verify
if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "$SOURCE_BRANCH" ]; then
echo "Skipping deploy; just doing a build."
doCompile
exit 0
fi
# Save some useful information
REPO=`git config remote.origin.url`
SSH_REPO=${REPO/https:\/\/github.com\//[email protected]:}
SHA=`git rev-parse --verify HEAD`
# Clone the existing gh-pages for this repo into out/
# Create a new empty branch if gh-pages doesn't exist yet (should only happen on first deply)
git clone $REPO out
cd out
git checkout $TARGET_BRANCH || git checkout --orphan $TARGET_BRANCH
cd ..
# Clean out existing contents
rm -rf out/**/* || exit 0
# Run our compile script
doCompile
# Now let's go have some fun with the cloned repo
cd out
git config user.name "Travis CI"
git config user.email "$COMMIT_AUTHOR_EMAIL"
# If there are no changes to the compiled out (e.g. this is a README update) then just bail.
if [ -z `git diff --exit-code` ]; then
echo "No changes to the output on this push; exiting."
exit 0
fi
# Commit the "changes", i.e. the new version.
# The delta will show diffs between new and old versions.
git add .
git commit -m "Deploy to GitHub Pages: ${SHA}"
# Get the deploy key by using Travis's stored variables to decrypt deploy_key.enc
ENCRYPTED_KEY_VAR="encrypted_${ENCRYPTION_LABEL}_key"
ENCRYPTED_IV_VAR="encrypted_${ENCRYPTION_LABEL}_iv"
ENCRYPTED_KEY=${!ENCRYPTED_KEY_VAR}
ENCRYPTED_IV=${!ENCRYPTED_IV_VAR}
openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in deploy_key.enc -out deploy_key -d
chmod 600 deploy_key
eval `ssh-agent -s`
ssh-add deploy_key
# Now that we're all set up, we can push.
git push $SSH_REPO $TARGET_BRANCH
HERE_DOC
cat >> .travis.yml << HERE_DOC
language: ruby
script: bash ./deploy.sh
rvm:
- 2.2
env:
global:
- ENCRYPTION_LABEL: "find-label-in-output"
- COMMIT_AUTHOR_EMAIL: "[email protected]"
HERE_DOC
cat >> _config.yml << HERE_DOC
exclude:
- Gemfile
- Gemfile.lock
- vendor
- deploy.sh
HERE_DOC
git add deploy.sh .travis.yml _config.yml deploy_key.enc
git commit -m "Adding travis deploy scripts"
Very usefull one line command when debugging travis
git add . && git commit --amend --no-edit && git push -f
You can edit online with http://prose.io. Make sure you are editing master
branch. Make sure github setting
https://github.com/duleorlovic/blog/settings/branches
default branch is master branch.
You can add prose related
config.
You can exclude files with ignore:
.
You can add custom fields for some front matter with metadata: _posts: ...
.
First key is folder name not the ruby class so if you have page or post inside
folder, than use folder name instead of _posts
.
Title is updated in header so do not need to define title metadata. Use ""
for
all files. Nice example of
prose.
Heroku
There is heroku buildpack than can build jekyll for you and serve static site so you can use any plugins. https://blog.heroku.com/jekyll-on-heroku
Serve under subfolder
Since github pages serve your project under subfolder
username.github.io/project-name
you need to use special config
variable baseurl
. Add to your
_config.yml
a line baseurl: /blog
. This is not needed if you use custom
domain like blog.trk.in.rs
To properly serve your assets and link your pages you need to prepend all links
with site.baseurl. For example in markdown ![My picture]({ { site.baseurl
}}/assets/my_picture.png)
or <link rel="stylesheet" href="{ { site.baseurl
}}/assets/css/main.css">
or <a class="post-link" href="{ { post.url | prepend:
site.baseurl }}">{ { post.title }}</a>
Development environment
If you need to separate production from development (for example analytics), you
can use liquid variable jekyll.environment
which can be exported or used
inline with JEKYLL_ENV=development jekyll serve --watch
<!-- index.html -->
<html>
<body>
{% if jekyll.environment == "development" %}
Hello admin
{% endif %}
</body>
</html>
Automatic deploy to gh-pages using rake
Rake tasks are perfect for deploying since you need just to type rake
and it
will be live (if you set up properly). This is my Rakefile that builds my blog
(stored on bitbucket) and push to github.
This is nice since I do not want to share history (all commits from the
beggining). On github, you can find only one commit “Site updated at …”
git remote add origin [email protected]:duleorlovic/trk.in.rs.git
git remote add github [email protected]:duleorlovic/trk.in.rs.git
# Rakefile
#
# You need to set up git remote to github, for example:
#
# git remote add github [email protected]:duleorlovic/blog.git
#
# Require jekyll to compile the site.
require "jekyll"
require 'tmpdir'
task :default => "blog:publish"
# Github pages publishing.
namespace :blog do
#
# Because we are using 3rd party plugins for jekyll to manage the asset pipeline
# and suchlike we are unable to just branch the code, we have to process the site
# localy before pushing it to the branch to publish.
#
# We built this little rake task to help make that a little bit eaiser.
#
# Usaage:
# bundle exec rake blog:publish
desc "Publish blog to gh-pages"
task :publish do
# Compile the Jekyll site using the config.
Jekyll::Site.new(Jekyll.configuration({
"source" => ".",
"destination" => "_site",
"config" => "_config.yml"
})).process
# Get the origin to which we are going to push the site.
origin = `git config --get remote.github.url`
# Make a temporary directory for the build before production release.
# This will be torn down once the task is complete.
Dir.mktmpdir do |tmp|
# Copy accross our compiled _site directory.
cp_r "_site/.", tmp
# Switch in to the tmp dir.
Dir.chdir tmp
# Prepare all the content in the repo for deployment.
system "git init" # Init the repo.
system "git add . && git commit -m 'Site updated at #{Time.now.utc}'" # Add and commit all the files.
# Add the origin remote for the parent repo to the tmp folder.
system "git remote add origin #{origin}"
# Push the files to the gh-pages branch, forcing an overwrite.
system "git push origin master:refs/heads/gh-pages --force"
end
# Done.
end
end
Moving away from gh pages so we can see the access logs
https://belief-driven-design.com/moving-from-github-pages-to-self-hosted-ab1231fb7fa/
Adding Table of Content
For README you can run command that extract all headers https://github.com/ekalinin/github-markdown-toc that you can copy and paste to README. Alternativelly you can insert
## Table of Contents
<!--ts-->
<!--te-->
and run
gh-md-toc --insert README.md
If you need automatic Toc for a any jekyll page than use dafi jekyll-toc-generator.
I modify to use original id-s (that is hypernated version of header content) in duleorlovic/jekyll-toc-generator
You can put defaults to not have a Toc, and enable on post that you want Toc to show.
# _config.yml
defaults:
-
scope:
path: ""
type: "posts"
values:
noToc: true
Adding sitemap
echo "gem 'jekyll-sitemap'" >> Gemfile
bundle
echo "url: https://trk.in.rs
gems:
- jekyll-sitemap
" >> _config.yml
Sitemap will be automatically generated with jekyll serve
. Add sitemap:
false
for pages that you don’t want to appear in sitemap (like google site
verification).
Jekyll variables and categories
Jekyll contains variables: site
,
layout
, content
, paginator
and page
.
{ { site }}
is Jekyll::Drops::SiteDrop
class and contains
site.posts
array of all posts objectsJekyll::Document collection=post
they are descending order. To access most recent you can use loop{ % for post in site.posts limit: 3 %}
or assign `` Inside loops you canbreak
orcontinue
. To filter based on specific property you can usewhere
<li> <a href="/2023/05/10/chatgpt/">Chatgpt</a> </li> <li> <a href="/2023/03/27/aws-tips/">Aws Tips</a> </li> <li> <a href="/2022/05/05/sidekiq_tips/">Sidekiq_tips</a> </li> <li> <a href="/2022/05/03/docker-deployment/">Docker Deployment</a> </li> <li> <a href="/2022/03/28/rails-terraform-aws-load-balancer/">Rails Terraform Aws Load Balancer</a> </li> <li> <a href="/2022/02/06/swift-xcode-ios/">Swift Xcode Ios</a> </li> <li> <a href="/2021/12/30/terraform-fundamentals/">Terraform Fundamentals</a> </li> <li> <a href="/2021/11/20/kubernetes/">Kubernetes</a> </li> <li> <a href="/2021/10/29/nginx/">Nginx</a> </li> <li> <a href="/2021/10/07/elektronsko-potpisivanje-apr-mup-citac-kartica-eporezi-na-virtual-box-windows-mac-linux/">Elektronsko Potpisivanje Apr Mup Citac Kartica Eporezi Na Virtual Box Windows Mac Linux</a> </li> <li> <a href="/2021/09/24/cloud-coding-play-with-rails/">Cloud Coding Play With Rails</a> </li> <li> <a href="/2021/07/13/rails-app-templates/">Rails App Templates</a> </li> <li> <a href="/2021/05/24/amazon-aws-sns-ses-workmail/">Amazon Aws Sns Ses Workmail</a> </li> <li> <a href="/2021/04/26/authorization_policy_cancan_pundit_action_policy/">Authorization_policy_cancan_pundit_action_policy</a> </li> <li> <a href="/2021/04/01/viber-api-bot/">Viber Api Bot</a> </li> <li> <a href="/2021/02/06/rubocop/">Rubocop</a> </li> <li> <a href="/2020/12/23/amazon-aws-ec2-auto-scaling-and-elastic-load-balancing/">Amazon Aws Ec2 Auto Scaling And Elastic Load Balancing</a> </li> <li> <a href="/2020/05/18/shopify-apps/">Shopify Apps</a> </li> <li> <a href="/2020/05/06/roblox-studio/">Roblox Studio</a> </li> <li> <a href="/2020/05/05/OBS-studio-stream-mobile-phone-cameras/">Obs Studio Stream Mobile Phone Cameras</a> </li> <li> <a href="/2020/04/07/metaprogramming-ruby/">Metaprogramming Ruby</a> </li> <li> <a href="/2020/03/25/cypress/">Cypress</a> </li> <li> <a href="/2020/03/05/machine-vision-davies/">Machine Vision Davies</a> </li> <li> <a href="/2020/02/27/opencv-computer-vision/">Opencv Computer Vision</a> </li> <li> <a href="/2020/02/01/amazon-aws-textract/">Amazon Aws Textract</a> </li> <li> <a href="/2020/01/23/trailblazer-dry-rb/">Trailblazer Dry Rb</a> </li> <li> <a href="/2020/01/21/dokku-paas/">Dokku Paas</a> </li> <li> <a href="/2020/01/15/scraping-capybara-mechanize-selenium/">Scraping Capybara Mechanize Selenium</a> </li> <li> <a href="/2019/12/24/activerecord-arel/">Activerecord Arel</a> </li> <li> <a href="/2019/12/23/amazon-aws-alexa-lamdba-skill-home-automation/">Amazon Aws Alexa Lamdba Skill Home Automation</a> </li> <li> <a href="/2019/11/23/decap-netlify-cms/">Decap Netlify Cms</a> </li> <li> <a href="/2019/10/21/google-ads-api/">Google Ads Api</a> </li> <li> <a href="/2019/10/03/payments/">Payments</a> </li> <li> <a href="/2019/10/01/progressive-web-apps-pwa/">Progressive Web Apps Pwa</a> </li> <li> <a href="/2019/09/17/jestjs-puppeteer/">Jestjs Puppeteer</a> </li> <li> <a href="/2019/09/10/expo-react-native/">Expo React Native</a> </li> <li> <a href="/2019/08/17/arduino-and-electronics/">Arduino And Electronics</a> </li> <li> <a href="/2019/06/10/shopify-theme/">Shopify Theme</a> </li> <li> <a href="/2019/04/23/d3-visualization/">D3 Visualization</a> </li> <li> <a href="/2019/03/26/service-workers/">Service Workers</a> </li> <li> <a href="/2019/03/25/es6-esnext/">Es6 Esnext</a> </li> <li> <a href="/2019/01/04/rails-translations-i18n/">Rails Translations I18n</a> </li> <li> <a href="/2018/12/10/java-in-android-studio/">Java In Android Studio</a> </li> <li> <a href="/2018/12/02/tableless-search-union-of-multiple-models-using-polymorphic-association-in-rails/">Tableless Search Union Of Multiple Models Using Polymorphic Association In Rails</a> </li> <li> <a href="/2018/12/01/nested-habtm-forms-for-associations-in-rails/">Nested Habtm Forms For Associations In Rails</a> </li> <li> <a href="/2018/11/30/object-oriented-design-principles-and-patterns/">Object Oriented Design Principles And Patterns</a> </li> <li> <a href="/2018/11/20/android-turbolinks-native-mobile-app-for-rails/">Android Turbolinks Native Mobile App For Rails</a> </li> <li> <a href="/2018/11/07/cordova/">Cordova</a> </li> <li> <a href="/2018/08/13/oauth-specification-doorkeeper/">Oauth Specification Doorkeeper</a> </li> <li> <a href="/2018/06/05/innovations-and-business/">Innovations And Business</a> </li> <li> <a href="/2018/05/31/sinatra/">Sinatra</a> </li> <li> <a href="/2018/05/30/rss-feed-reader/">Rss Feed Reader</a> </li> <li> <a href="/2018/05/24/hotwire-turbo-websockets-actioncable/">Hotwire Turbo Websockets Actioncable</a> </li> <li> <a href="/2018/05/18/ruby-http-client/">Ruby Http Client</a> </li> <li> <a href="/2018/05/17/gdpr-privacy-policy-and-terms-of-use/">Gdpr Privacy Policy And Terms Of Use</a> </li> <li> <a href="/2018/04/16/let-me-see/">Let Me See</a> </li> <li> <a href="/2018/04/10/continuous-delivery-integration-ci-cd-pronto/">Continuous Delivery Integration Ci Cd Pronto</a> </li> <li> <a href="/2018/03/22/stimulus-js/">Stimulus Js</a> </li> <li> <a href="/2018/02/21/blockchain-bitcoin-etherium/">Blockchain Bitcoin Etherium</a> </li> <li> <a href="/2018/02/12/mikrotik-routers-winbox/">Mikrotik Routers Winbox</a> </li> <li> <a href="/2018/01/26/hanami/">Hanami</a> </li> <li> <a href="/2018/01/22/minitests-rails/">Minitests Rails</a> </li> <li> <a href="/2017/11/17/sharetribe/">Sharetribe</a> </li> <li> <a href="/2017/10/05/google-apis-gmail-calendar-youtube-captcha/">Google Apis Gmail Calendar Youtube Captcha</a> </li> <li> <a href="/2017/10/02/vue-js/">Vue Js</a> </li> <li> <a href="/2017/08/29/stripe/">Stripe</a> </li> <li> <a href="/2017/08/18/shopify-api/">Shopify Api</a> </li> <li> <a href="/2017/08/15/typescript-begginer-examples/">Typescript begginer examples</a> </li> <li> <a href="/2017/08/10/angular-4-and-beyond/">Angular 4 And Beyond</a> </li> <li> <a href="/2017/07/11/graphql/">GraphQL</a> </li> <li> <a href="/2017/06/16/move-index/">Move Index opensource</a> </li> <li> <a href="/2017/06/05/vim-theory/">Vim theory</a> </li> <li> <a href="/2017/05/23/macbook-macos-osx/">MacBook MacOS OSX</a> </li> <li> <a href="/2017/05/16/state-machines-audit-trail-gem/">State machines audit trails gem</a> </li> <li> <a href="/2017/05/03/bootstrap-front-end-framework/">Bootstrap front-end framerwork</a> </li> <li> <a href="/2017/02/23/http-theory/">HTTP theory</a> </li> <li> <a href="/2017/02/13/datatables/">Datatables</a> </li> <li> <a href="/2017/02/03/rails-cache/">Rails cache</a> </li> <li> <a href="/2017/01/10/get-syntax-right-in-jade-yaml-haml/">Get Syntax Right In Jade Yaml Haml</a> </li> <li> <a href="/2016/10/28/adminlte-free-template-on-rails/">AdminLTE Free Template on Rails</a> </li> <li> <a href="/2016/10/19/elm-functional-static-typed-language/">Elm functional static typed language</a> </li> <li> <a href="/2016/09/14/web-vulnerability-and-dos-attacks/">Web Vulnerability And Dos Attacks</a> </li> <li> <a href="/2016/09/13/ubuntu-working-environment/">Ubuntu working environment</a> </li> <li> <a href="/2016/09/12/ruby-math-hackerrank/">Ruby Math Hackerrank</a> </li> <li> <a href="/2016/09/07/cap3-capistrano-deployment-rubber-provision/">Cap3 Capistrano Deployment Rubber Provision</a> </li> <li> <a href="/2016/08/26/background-jobs-and-queues/">Background jobs and queues</a> </li> <li> <a href="/2016/08/20/ionic-3/">Ionic 3</a> </li> <li> <a href="/2016/08/16/api-design/">Api design</a> </li> <li> <a href="/2016/07/26/usefull-plugins-services-and-opensource-stuff/">Usefull plugins, services and opensource stuff</a> </li> <li> <a href="/2016/05/31/apns-gcm-push-notifications-using-ionic/">Apns Gcm Push Notifications Using Ionic</a> </li> <li> <a href="/2016/05/26/mysql/">Mysql</a> </li> <li> <a href="/2016/05/22/neo4j-rails/">Neo4j Rails</a> </li> <li> <a href="/2016/05/18/echo-sed-grep-command-line-editing/">Echo Sed Grep command line editing</a> </li> <li> <a href="/2016/05/17/send-and-receive-emails-in-rails/">Send and receive emails in rails</a> </li> <li> <a href="/2016/05/05/git-tips/">Git tips</a> </li> <li> <a href="/2016/04/27/scalable-css/">Scalable css</a> </li> <li> <a href="/2016/04/20/bundler-bower-gulp-npm-yarn-webpack-tips/">Bundler Bower Gulp Npm Yarn Webpack Tips</a> </li> <li> <a href="/2016/04/13/css-and-html-tips/">Css And Html Tips</a> </li> <li> <a href="/2016/04/12/rails-tips/">Rails Tips</a> </li> <li> <a href="/2016/04/07/angular-errors/">Angular errors</a> </li> <li> <a href="/2016/04/05/javascript-coffeescript-tips/">Javascript & coffeescript tips</a> </li> <li> <a href="/2016/03/02/gulp-tasks/">Gulp tasks</a> </li> <li> <a href="/2016/02/29/amazon-aws-s3/">Amazon AWS S3</a> </li> <li> <a href="/2016/02/21/zoneminder-security-server-raspberry-pi-home-automation-arduino/">Zoneminder security server and Raspberry Pi home automation</a> </li> <li> <a href="/2016/02/19/angular-material/">Angular Material</a> </li> <li> <a href="/2016/02/10/javascript-theory/">Javascript theory</a> </li> <li> <a href="/2016/02/01/bash/">Bash</a> </li> <li> <a href="/2016/01/27/ionic-begginer-examples/">Ionic Begginer Examples</a> </li> <li> <a href="/2016/01/08/testing-in-javascript/">Testing in javascript</a> </li> <li> <a href="/2015/12/24/ionic-direct-aws-s3-upload/">Ionic & Rails Direct S3 image upload</a> </li> <li> <a href="/2015/12/20/devise-oauth-angular/">From simple Devise to Oauth on Angular</a> </li> <li> <a href="/2015/12/18/angular-testing/">Angular Testing</a> </li> <li> <a href="/2015/12/10/angular-begginer-examples/">Angular begginer examples</a> </li> <li> <a href="/2015/12/01/vim-tips/">Vim</a> </li> <li> <a href="/2015/11/26/angular-and-ruby-on-rails/">Angular 1.x and Ruby on Rails</a> </li> <li> <a href="/google/location-suggestion/maps/2015/11/20/google-maps-and-locations/">Google Maps and Locations</a> </li> <li> <a href="/2015/11/11/seo-optimization-advices/">Seo Optimization Advices</a> </li> <li> <a href="/2015/11/09/rails-testing/">Rails Testing</a> </li> <li> <a href="/2015/11/07/ruby-books/">Ruby Books</a> </li> <li> <a href="/2015/10/08/free-ssl-for-https-on-apache-or-nginx/">Free Ssl For Https On Apache Or Nginx</a> </li> <li> <a href="/2015/10/01/jekyll-tips-for-github-pages/">Jekyll tips for github pages</a> </li> <li> <a href="/2015/09/10/ruby-memory-leak-track/">Ruby memory leak trackdown</a> </li> <li> <a href="/2015/08/22/svg-css3-transforms-and-animations/">Svg Css3 Transforms And Animations</a> </li> <li> <a href="/2015/07/07/postgresql-tricks/">Postgresql Tricks</a> </li> <li> <a href="/2015/04/05/common-rails-bootstrap-snippets/">Common Rails bootstrap snippets</a> </li> <li> <a href="/2015/03/04/rails-settings-in-cache-and-beta-features/">Rails Settings In Cache And Beta Features</a> </li> <li> <a href="/2015/02/16/rails-through-vagrant-to-digitalocean/">Rails through Vagrant to DigitalOcean</a> </li> <li> <a href="/2015/01/11/good-rails-exception-notification-better-than-tests/">Good rails exception notifier better than tests</a> </li> <li> <a href="/2014/09/02/ruby-on-rails-with-ajax-javascript/">Ruby on rails and Ajax javascript</a> </li> <li> <a href="/2014/07/03/ruby-on-rails-polymorphic-or-sti/">RoR polymorphic or sti</a> </li> <li> <a href="/2014/07/01/ruby-on-rails-layouts-and-rendering/">Ruby on Rails Layouts and rendering</a> </li>
site.pages
array of all pagesJekyll::Page
{ { page }}
is an object with
page.content
preproccessed contentpage.name
likecontact.md
page.path
likeexample/contact.md
-
page.url
like/example/contact.html
- all front matters variables like
page.layout
,page.title
if current page is post
we have additional properties
page.title
page.excerpt
it is first paragraph. if you need to limit you can usehttps://github.com/f/awesome-chatgpt-prompts
. You can use specific delimiter on a post in frontmatterexcerpt_separator: <!--more-->
or in config (but than default “paragraph” excerpt will not be used, and you need to use separator on every post)page.date
page.id
page.categories
page.tags
page.next
page.previous
can be used to link to previous post<a href="/2015/09/10/ruby-memory-leak-track/">« Ruby memory leak trackdown</a>
You can put your posts inside folder, for examle kayak/canoe/_posts
. This
means that posts will have ['kayak', 'canoe']
categories. You can add more
categories using front matter categories: sprint
.
Since pages do not have category, you cat mark them manually or check path, like this
{ % capture page_category = page.path | split: '/' | first %}
To list similar posts you can use this snippet in _layout/default.html
<style type='text/css'>
.similar-links {
display: inline-block;
padding: 10px;
}
</style>
{% for cat in page.categories %}
{% if site.categories.[cat].size != 1 %}
<ul class="similar-links">
<li>Look similar <b> {{ cat }}</b> tag:</li>
{% for p in site.categories.[cat] %}
{% unless p.url == page.url %}
<li>
<a href="{{ p.url }}">{{ p.title }}</a>
</li>
{% endunless %}
{% endfor %}
</ul>
{% endif %}
{% endfor %}
Search
Just copy and paste search.json
and other snippets from
Simple-Jekyll-Search
404
For gh-pages, you just need 404.html
at root for server to use it when it does
not find the page.
Config
You can serve using different port, just add port: 4001
to your _config.yml
file or using --port
attribute (-p
does not work)
jekyll s --port 4001
For jekyll-postcss the port 8124 is hardcoded so if you want to change than update two files
bundle open jekyll-postcss
bin/postcss
lib/jekyll-postcss/socket.rb
Theme
If you want to create theme you can follow this steps:
jekyll new-theme jekyll-theme-booster
vi jekyll-theme-booster.gemspec
# edit description and url
gem build jekyll-theme-booster.gemspec
gem install jekyll-theme-booster-0.1.0.gem
Running example site
You can put posts inside root folder but than you do not know which file belongs
to theme and which is just example. So better is to use separated folder and use
rake example
to run that site.
# Rakefile
# based on
# https://github.com/mmistakes/minimal-mistakes/blob/master/Rakefile
require "bundler/gem_tasks"
require "jekyll"
require "listen"
def listen_ignore_paths(base, options)
[
/_config\.ya?ml/,
/_site/,
/\.jekyll-metadata/
]
end
def listen_handler(base, options)
site = Jekyll::Site.new(options)
Jekyll::Command.process_site(site)
proc do |modified, added, removed|
t = Time.now
c = modified + added + removed
n = c.length
relative_paths = c.map{ |p| Pathname.new(p).relative_path_from(base).to_s }
print Jekyll.logger.message("Regenerating:", "#{relative_paths.join(", ")} changed... ")
begin
Jekyll::Command.process_site(site)
puts "regenerated in #{Time.now - t} seconds."
rescue => e
puts "error:"
Jekyll.logger.warn "Error:", e.message
Jekyll.logger.warn "Error:", "Run jekyll build --trace for more information."
end
end
end
task :example do
base = Pathname.new('.').expand_path
options = {
"source" => base.join('example').to_s,
"destination" => base.join('example/_site').to_s,
"force_polling" => false,
"serving" => true,
"theme" => "jekyll-theme-booster"
}
options = Jekyll.configuration(options)
ENV["LISTEN_GEM_DEBUGGING"] = "1"
listener = Listen.to(
base.join("_includes"),
base.join("_layouts"),
base.join("_sass"),
base.join("assets"),
options["source"],
:ignore => listen_ignore_paths(base, options),
:force_polling => options['force_polling'],
&(listen_handler(base, options))
)
begin
listener.start
Jekyll.logger.info "Auto-regeneration:", "enabled for '#{options["source"]}'"
unless options['serving']
trap("INT") do
listener.stop
puts " Halting auto-regeneration."
exit 0
end
loop { sleep 1000 }
end
rescue ThreadError
# You pressed Ctrl-C, oh my!
end
Jekyll::Commands::Serve.process(options)
end
Editing theme
Only files that are in repository are used for gem. gemspec uses git ls-files
and default gemspec is to inlude assets
, _includes
, _layouts
and _sass
.
You can see what is in gem with gem open jekyll-theme-booster
.
Some files will not be used: _config.yml
.
Using theme
When you edit template, you need to build, install and restart your jekyll serve proccess to load updated gem.
It is enough to specify
path as <link rel="stylesheet" href="assets/css/animate.css">
but for relative
folder <link rel="stylesheet" href="{ { "assets/css/animate.css" | relative_url }}">
(that is needed for all navigational links).
It is advised to be in same ruby version rvm list
and rvm gemset list
.
Another theme example is minimal-mistakes-jekyll
Yet another theme https://tympanus.net/codrops/2018/04/20/freebie-oasis-jekyll-website-template
Markdown
- table
can be generated with
|header1|header2
- url can be written like
<http://projektor.trk.in.rs>
(http://
at the beggining is mandatory) instead of writting it twice[http://projektor.trk.in.rs](http://projektor.trk.in.rs)
- internal link to post is with
{% link %}
orpost_url
[My page]({ % link _posts/2016-03-02-my-page.md %}) [My page]({ % post_url 2016-03-02-my-page %})
- images
![alt text]({ { site.baseurl }}/assets/path_to_image "Title text")
If you want to use image inREADME.md
than you need to store image and use full path to raw file. No spaces are allowed, file path should be one string without quotes. Path should be raw (not sure why relative path does not work) https://github.com/[username]/[reponame]/blob/[branch]/image.jpg?raw=true![trk-datatables](test/trk_datatables_with_daterangepicker.png "TRK Datatables")
This will work on github but not if README is shown on other sites
- strikethrough (words crossed, deleted, removed text) can be used with
<s>Example</s>
or<del>Example</del>
(with kramdown no shortcut works like-- ~~
) - for code you can use
{% highlight javascript %}
,{% highlight ruby %}
,{% highlight bash %}
- use inline html in markdown if you use span level tags
<span>
,<bold>
… for block level tags<div>
you need to add blank line.
Kramdown
- inline and block html elements
We have old router <div class='pull-right'> Text right </div> {::options parse_block_html="true" /} <div> Use *markdown* for span elements </div>
- definition list dl dt dd
term inside dt : definition inside dd
- block attributes are set with folloing IAL inline attribute list
> A blockquote {: title="My title" .class1 #my-id}
- share attributes using ALD atribute list definition
{:refdef: .my-class} paragraph {: refdef}
- span level elements using IAL inline attribute list
This is *red*{: style='color: red'}.
- extension using ::, like
::comment
My {::comment} this is ignored completely {:/comment} paragraph
Liquid in markdown
- to show jekyll mustache inline you can add space, like
{ % bla_tag %}
. Note that in blocks of code you can use mustache, so this is only for inside tick. - to show
{{ }}
using markdown you need to escape them like{{ '{{ ' }} }}
first closing brackets will close everything that comes after first opening brackets. All other closing brackets are simply rendered. This does not work if that line breaks in mutliple lines (probably string need + or something). To simplify I just put space between first{ { }}
- if you need to show ` than use backslash or put a space ` so it wont be applied`
Internal jekyll tags
link
Note that you do not have to use quotes: '
or "
.
{ % post_url %}
. Note that you can not use string filters likeprepend:
inside tags (works only with double curly brackets{ { }}
, so for link to another post (by it’s file name) whensite.baseurl
is set, you need[my-post]({ { site.baseurl }}{ % post_url 2015-12-20-my-post %})
- when you want to link assets you can use
{ { "/assets/style.css" | relative_url }}
- you can link to (link_to) pages also (not just posts) with
{ { site.baseurl }}{ % link news/index.html %}
. Parameter forlink
should contain extension (for example.md
).
For string manipulation you can use replace
filters. For interpolation you
need to use capture
/blog/2015/10/01/jekyll-tips-for-github-pages/
Note that in liquid version 4 you can use concat
filter but it is not
supported in jekyll 3.4 (liquid 3.0.6) concat
example.
In old liquid you can use append
but that is only for strings.
You should point to latest jekyll from github which uses Liquid 4
# get latest jekyll which uses liquid 4
gem "jekyll", github: 'jekyll/jekyll'
Adding tag, filter
All plugins will be loaded from _plugins
folder. Githib ignore this folder.
# _plugins/alert_tag.rb
module Jekyll
module AlertFilter
def alert(text)
unescaped = if text.class == String
CGI.unescapeHTML text
else
text.to_s
end
%(<script>
alert('#{unescaped}');
</script>)
end
end
end
Liquid::Template.register_filter(Jekyll::AlertFilter)
This is used to alert text { % alert this is text %}
# _plugins/alert_filter.rb
module Jekyll
module AlertFilter
def alert(text)
unescaped = if text.class == String
CGI.unescapeHTML text
else
text.to_s
end
%(<script>
alert('#{unescaped}');
</script>)
end
end
end
Liquid::Template.register_filter(Jekyll::AlertFilter)
Filter is used like { { page | alert }}
Scss
For adding scss support, you need to put your main scss file inside for example
assets/main.scss
and it needs to have double three lines ---
. From there you
can use @import "file_from_scss";
to load partials from _sass
folder
---
# this is assets/main.sass which imports other sass files
# NOTE that you can not import css file, it needs to be sass/scss
# import "file.css" # this will not be imported at compile time, but in browser
# import "file" # this will search for file.sass and import at compile time
---
@import "overrides";
<!-- override default template file _includes/head.html -->
...
<link rel="stylesheet" href="/assets/main.css">
Coffee script
To enable coffee script you need to add to config.yml
cat >> _config.yml << HERE_DOC
gems:
- jekyll-coffeescript
HERE_DOC
And you coffee files need to have three lines ---
for example
---
# assets/js/cart.coffee
---
class Cart
constructor: (@buttons, @cart) ->
@buttons.click (event) =>
@textContent = 'Added'
do event.preventDefault
itemContainer = event.target.parentNode.parentNode.parentNode
itemNumber = do $ itemContainer
.find 'h3.panel-title'
.text
listItem = do $ @cart
.find 'li:last'
.clone
listItem.text itemNumber
@cart.append listItem
.hide()
.fadeIn 'slow'
console.log itemContainer
$ ->
cart = new Cart $('form button'), $('ul#cart')
and they will be compiled, so you can include them <script
src="assets/js/cart.js"></script>
Rails
https://www.sitepoint.com/jekyll-rails/ Example on https://github.com/trkin/premesti.se/tree/master/blog
Tips
- if you want to move page it is advised to leave old page some time so you do not confuse crawlers. The best is to add redirection in html so that you do not add duplicate posts
# mkdir -p 2023/01/04
# 2023/01/04/intership.html
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="refresh" content="1;url=https://www.trk.in.rs/2023/01/04/internship.html"/>
<link rel="canonical" href="https://www.trk.in.rs/2023/01/04/internship.html"/>
<script type="text/javascript">
window.location.href = "https://www.trk.in.rs/2023/01/04/internship.html"
</script>
<title>Page Redirection</title>
</head>
<body>
If you are not redirected automatically, follow <a href='https://www.trk.in.rs/2023/01/04/internship.html'>this link</a>.
</body>
</html>
If you have a lot of redirections, you can use different layout
# _layouts/redirect.html
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="refresh" content="1;url="/>
<link rel="canonical" href=""/>
<script type="text/javascript">
window.location.href = ""
</script>
<title>Page Redirection</title>
</head>
<body>
If you are not redirected automatically, follow <a href=''>this link</a>.
</body>
</html>
and define redirection in markdown. Since jekyll does not support using liquid in frontmatter you have to specify whole url
# _posts/2022-02-02-old-page.md
---
layout: redirect
redirect: https://www.example.org
---
Slides
Google io slides can be found https://github.com/willnorris/io-slides After you clone the repository
Tips
https://jekyllrb.com/docs/plugins/ https://github.com/planetjekyll/awesome-jekyll https://github.com/planetjekyll/awesome-jekyll-plugins
https://mademistakes.com/articles/using-jekyll-2016/
- date
2024
- add bootstrap
yarn init yarn add bootstrap jquery popper.js # _config.yml sass: load_path: - _sass - node_module # css/main.sass
- debug slow rendering with
jekyll s --profile --verbose --trace
To render only last post
jekyll s --watch --limit_posts 1
Rebuild only that is changed
jekyll s --incremental
- permalinks only support date and categories. To use author in permalink you need to use plugin https://gist.github.com/peey/897e8ed33e412fdfe0fcacf002acc150
-
seo tags and Open Graph meta name tags are added using https://github.com/jekyll/jekyll-seo-tag
-
jekyll with webpack https://github.com/sandoche/Jekyll-webpack-boilerplate To add boootstrap, run
npm add bootstrap jquery popper.js
and add// _src/index.js import 'jquery'; import 'popper.js'; import 'bootstrap'; // _src/index.scss @import '~bootstrap/scss/bootstrap';
For links you need to use relative url
<a href="/2023/05/10/chatgpt/">Chatgpt</a>
I disabled minify_html so it runs faster on development https://github.com/sandoche/Jekyll-webpack-boilerplate/pull/26
To rebuild you need to stop and start again
npm start
- data is yml and you can access
# _data/prices.yml kajak_jednosed: 800 kajak_dvosed: 1200
similarly you can translate
# _data/t.yml title: en: Hi sr: Cao
- code samples https://github.com/bwillis/jekyll-github-sample https://bwillis.github.io/2014/05/28/include-github-repo-code-in-jekyll/
- for error for ruby 3
/home/orlovic/.rvm/gems/ruby-3.0.2/gems/jekyll-4.2.1/lib/jekyll/commands/serve/servlet.rb:3:in `require': cannot load such file -- webrick (LoadError)
you just need to add gem
bundle add webrick
- for error
Could not find sass-embedded-1.58.3-x86_64-linux in any of the sources
solution is to remove Gemfile.lock
- good readme file: include repo url, screenshot or video, toc (TODO: vim
script)
```
My Project
My description
This repo is hosten on Github
https://github.com/duleorlovic/tailwind_play_responsive_dark_mode
Preview
Here is a preview how I updated button color only in dark mode
Screencast from 07.03.2023. 12:01:13.webm
Local develoment
Live Demo
Authors ✍️
https://github.com/duleorlovic
🤝 Contributors
Contributions, issues, and feature requests are greatly appreciated!
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag “improvements”.
- Fork the Project
- Create your Feature Branch (git checkout -b feature/yourfeaturename)
- Commit your Changes (git commit -m ‘Add suggested feature’)
- Push to the Branch (git push origin feature/AmazingFeature)
- Open a Pull Request
Feel free to check the issues page.
📝 License
Show your support 💪
Give a ⭐️ if you like this project!
```
Just the docs
- source https://github.com/just-the-docs/just-the-docs
- documentation https://just-the-docs.com/
- demo https://just-the-docs.github.io/just-the-docs-template/
- to use the template go to https://github.com/just-the-docs/just-the-docs-template/generate It will be live under username.github.io/reponame but you can set to your domain by adding CNAME record with value username.github.io. If you receive error “redirected you too many times ERR_TOO_MANY_REDIRECTS than enable Full instead of Flexibly encryption on Cloudflare. This can be on per host basis Note that custom hostname requires to change relative