Configuring Jekyll for Github Project Pages

Configuring Jekyll for github PROJECT pages

When you have a slash at the front of your permalink, it means that all URLs should be relative to the site root. This is the reason that it's going to http://corroded.github.com/exercises/title-here instead of http://corroded.github.com/projectname/exercises/title-here. Try it without the first slash:

permalink: exercises/:title

The same thing goes for any URLs you create with HTML. If you have:

<a href="/about">

it will always go to the root of the domain (e.g. http://corroded.github.com/about). If you're project is called 'projectname', you can use HTML like

<a href="/projectname/about">

to link directly to pages (e.g. http://corroded.github.com/projectname/about).

Of course, you can also use relative URLs (i.e. URLs without a leading slash) as well. You just have to be aware of where you are in the directory tree.

How to use theme from github.io site for Github Project Pages sites

Yesterday I finally went through and did what I theorized about in September. The result lives here now. This was not an easy process, despite the documentation trying to be helpful, because the intersection of Jekyll and GitHub pages is such a massively complicated opaque box, and ruby was unfamiliar to me. But ultimately it boils down to a few important steps and gotchas:

  1. You're gonna need ruby and several packages. sudo apt install ruby should give you ruby (interpreter) and gem (package manager).

    • Gotcha 1a: The basics are left unexplained, so allow me: Ruby code comes in packages called gems, which are a lot like python packages. They're managed by gem or bundler rather than pip and hosted on rubygems.org instead of pypi. Much like in the Python world where everyone sings the praises of conda, everyone in the Ruby world sings the praises of bundler, which is itself a gem, one that you have to gem install because it doesn't come packaged with ruby like gem itself. I found bundler to be buggy; it hung when I tried to bundle install github-pages (more on github-pages later). Also, bundler relies on yet more configuration files called Gemfiles, which are the analog of the requirements.txt files pip can but doesn't need to ingest. Honestly who wants more of that clutter lying around for a small project with no complicated dependency tree? And who wants to have to bundle exec jekyll serve instead of just jekyll serve? Are you kidding me? Just use gem to install things, and skip the Gemfile. Much like pip, I find simpler is better.
    • Gotcha 1b: If you sudo apt install jekyll, you get an old version, like 3.1 or something. But Jekyll is a gem; you can and should install using the package manager. (But actually don't do this, because it comes as part of the github-pages gem, and the versions don't agree. More on that later.)
    • Gotcha 1c: Oh, what's that? You want to gem install jekyll (or even gem install bundler)? Yeah, sorry, I can't do that because there's some stuff missing, and here's a long printout about it. ...Google, Google... sudo apt install ruby-dev. Oh, sorry I still can't build. Here are some other errors. ...Google, Google... sudo apt install g++. Okay now it works. This process might be slightly different for you; point is setting up a ruby environment can be dicey.
    • Gotcha 1d: Oh what's that? Now you want to be able to call jekyll from the command line like you could if you just installed it with apt? Well, sorry, I'm gem, and some times I don't put jekyll on your path. If this happens to you, pay attention to where gem saves the gems, go find the executable within, and then create a symlink with sudo ln -s /path/to/jekyll /usr/bin/jekyll
  2. Move assets, _includes, _layouts, and _sass from the site to a new repo. Done. Bam. You have a remote theme now. It really should be that easy, but...

    • Gotcha 2a: No one tells you that's the minimum viable product, so you have to start by understanding what remote themes are and how they work. According to canon, they're full-blown gems. When you reference one, Jekyll needs to go and fetch it before it can generate your site. The Jekyll documentation is all about coaching you on how to truly package up your theme as a gem and push it up to rubygems.org, which requires: (1) a rubygems account, (2) for your theme to contain an abstruse .gemspec file, the contents of which are not well explained. Keep reading for why this is irrelevant.
    • Gotcha 2b: You have to understand how GitHub Pages actually uses remote themes. On this topic GitHub is happy to tell you about adding remote_theme: user/theme-name to the leveraging site's _config.yml (Jekyll config), but they neglect to tell you upfront whether they're pulling in a gem from somewhere or what. Turns out they're using yet another gem called jekyll-remote-theme to pull the raw files directly from a repo, making the step of compiling and uploading a gem and having a .gemspec no one understands or wants to look at unnecessary. (Hooray.) benbalter's documentation for the remote theme gem itself is the only place I could find this information.
    • Gotcha 2c: Beware that because Pages is still on Jekyll 3.8.6, you don't have certain functionality on GitHub Pages that you might want, like being able to define site data in the theme's _config.yml. As a result, my front-matter-prepended .css containing a few Liquid tags that worked just fine as part of my unseparated site ended up with emptystring tag substitutions in the generated site. I ended up hard-coding some variables in the theme.
    • Gotcha 2d: Any other folders and files--not among assets, _includes, _layouts, and _sass--(I had one named theme containing stuff like my favicon.) don't get folded in to a theme gem or transported via the jekyll-remote-theme mechanism employed by GitHub. By carefully amending the .gemspec, you can include those files in a gem, but this method has no effect on the behavior of jekyll-remote-theme, so I ended up basically putting everything in assets.
    • Complaint 2e: Ruby Sass is apparently deprecated now? Why has Jekyll continued to use it for so long? I've still not encountered an example where it seems useful.
  3. Put a _config.yml containing remote_theme: yourname/yourtheme in the root directory of the gh-pages branch of every repo for which you want the Project Pages rendered in your theme. No Gemfile, no nonsense. Just wait for it to deploy.

    • Gotcha 3a: Jekyll looks specifically for a page.html file inside _layouts to render readme contents. If you have a page.html, then you can add your head, navbar and other _includes stuff to it with Liquid tags no problem. If you happened to forget this file or think Jekyll could use post.html instead, well then you'd be wrong, and the theme isn't applied. Not sure whether default.html would work as a failover. In any case, GitHub pages with Jekyll is super brittle, and I'm honestly lucky to have discovered this without being blocked by it, because (1) I haven't seen any GitHub documentation to describe exactly which commands are being called to generate Project Pages, (2) you can't see the terminal output for the remote compilation process**, and (3), because you don't know what GitHub is doing, there is no way to replicate it locally to see warnings or error printouts--that is if Jekyll even warns you about this.

      **If there actually is a way to view this somewhere, please tell me. GitHub says: "When you push changes to your publishing source on GitHub, GitHub Pages will attempt to build your site. If the build fails, you'll receive an email at your primary email address. You'll also receive emails for build warnings. You can see build failures (but not build warnings) for your site on GitHub in the Settings tab of your site's repository." I did receive an email stating "The tag include_cached on line 15 in /_layouts/default.html is not a recognized Liquid tag.", but I don't remember which build this was for, and I can't find the failure recorded in the repo Settings anywhere.
    • Gotcha 3b: If you update the theme, Pages sites which use the theme aren't rebuilt to reflect the theme changes. You have to manually repush to the branch a site is built from to trigger a site rebuild. This is pretty easy for repos I've integrated with Travis-CI, because I can just go down the list rerunning the most recent builds, which culminate in pushes to gh-pages branches, which in turn cause Pages servers to rebuild. But for other sites, I have to either make some legitimate change or push an empty commit.
  4. Add plugins: - jekyll-remote-theme and remote_theme: yourname/yourtheme to the _config.yml in your User Pages site.

    • Gotcha 4a: Local execution is confusing. benbalter's readme is pretty good, but the Usage section still assumes you're using bundler. If you're not, then gem install github-pages like you'd install any other gem. This gem is really a huge list of other gems Pages servers actually run to generate your static site, including the same versions of jekyll and jekyll-remote-theme. You'll want these so you can catch all subtle version or display bugs locally and have no surprises in the cloud. Finally, despite it not seeming to be necessary for actual deployment, for local execution you have to make sure to list jekyll-remote-theme as a plugin in your leveraging site's _config.yml. Otherwise jekyll serve errors.
    • Gotcha 4b: Local execution with a remote theme is broken--or at least it is for Jekyll 4.0.0. It works fine for Jekyll 3, which is what GitHub Pages servers use, which is why it deploys fine. If you get Jekyll with gem install jekyll rather than from the github-pages list, you might get errors as I did.

So basically it's not hard in hindsight, but getting there is a frustrating fiasco of flying blind with only overly verbose, disappointingly incomplete maps to guide you. I wish GitHub would show you the whole process of site compilation and deployment in some terminal, like Travis-CI does for builds. And I wish Jekyll weren't so complicated. There are too many features, and too many things fail silently.

I hope this research can help somebody else.

How do I configure GitHub to use non-supported Jekyll site plugins?

Depending if you deal with a User/Organization (UO) site or a Project site (P), do :

  1. from your working folder git init
  2. git remote add origin git@github.com:userName/userName.github.io.git (UO) or git remote add origin git@github.com:userName/repositoryName.git (P)
  3. jekyll new . creates your code base
  4. in _config.yml, set the baseurl parameter to baseurl: '' (UO) or baseurl: '/repositoryName' (P)
  5. in .gitignore add _site, it will be versioned in the other branch
  6. jekyll build will create the destination folder and build site.
  7. git checkout -b sources (UO) or git checkout master (P)
  8. git add -A
  9. git commit -m "jekyll base sources" commit your source code
  10. git push origin sources (UO) or git push origin master (P) push your sources in the appropriate branch
  11. cd _site
  12. touch .nojekyll, this file tells gh-pages that there is no need to build
  13. git init init the repository
  14. git remote add origin git@github.com:userName/userName.github.io.git (UO) or git remote add origin git@github.com:userName/repositoryName.git (P)
  15. git checkout master (UO) or git checkout -b gh-pages (P) put this repository on the appropriate branch
  16. git add -A
  17. git commit -m "jekyll first build" commit your site code
  18. git push origin master (UO) or git push origin gh-pages (P)

You now have something like Octopress does. Look at their rake file, there are some nice comments inside.

Configure GitHub Pages syntax highlighting identical to GitHub

GitHub uses a closed syntax highlighting library not available on GitHub Pages. Supposedly, it should be possible to get a reasonable result using the default Jekyll highlighter. However, for me it was simpler to switch to the highlight.js JS library. Here are the steps.

  1. Disable Jekyll's highlighter in the _config.yml

  2. Obtain the highlight.min.js library

    • Prebuilt library is available from the website or via CDNs.
    • A custom version can be generated online, if necessary.
  3. Obtain a CSS theme file

    Specific CSS theme can be picked chosen using online demo service. CSS files are also available via CDNs or can be downloaded for local access.

  4. Load the library, theme file, and initialize the library

    In my case, I placed the library in /assets/js/highlight.min.js and included the following lines in /_includes/head_custom.html

  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/github.min.css">
<script type="text/javascript" src="{{ '/assets/js/highlight.min.js' | relative_url }}"></script>
<script>hljs.highlightAll();</script>

I also included a CSS element /_sass/custom/custom.scss in to overwrite code block background:

.hljs {background: #fdfdfa !important;}

Setting Jekyll environment for GitHub Pages

After a lot of trial and error, I finally figured out how to fix this issue. For whatever reason, the answer provided by @Christian Specht (using two different config files wasn't working). Instead I had to manually change the environments using the child process spawns in my gulp tasks. My updated gulpfile.js:

/**
* Build the Jekyll Site
*/
gulp.task('jekyll-build', function (done) {
browserSync.notify(messages.jekyllBuild);
return cp.spawn('jekyll', ['build'], { stdio: 'inherit' })
.on('close', done);
});

/**
* Build the Jekyll Site for production
*/
gulp.task('jekyll-build-prod', function (done) {
browserSync.notify(messages.jekyllBuild);

var productionEnv = process.env;
productionEnv.JEKYLL_ENV = 'production';

return cp.spawn('jekyll', ['build'], { stdio: 'inherit' , env:productionEnv })
.on('close', done);
});

/**
* Deploy to gh-pages
*/
gulp.task('deploy', ['jekyll-build-prod'], function() {
return gulp.src('./_site/**/*')
.pipe(ghPages());
});

GitHub pages serving from docs and jekyll source folder config

Is Jekyll's documentation unclear. Yes.

New github pages publication branch/folder :

Available options are (doc) :

  • gh-pages branch
  • master branch
  • master branch /docs folder
  • Disable GitHub Pages.

Three first options defines your root publication folder.

Github pages uses this root folder to generate your site. You cannot override source key in your _config.yml.

Your can store your sources in a _docs folder and output in docs

- project
| - _docs
| | content
| | files
| | tools
|
| - docs << output here


Related Topics



Leave a reply



Submit