Home >Technology peripherals >It Industry >Hacking a Routing Component in Jekyll
Initially I was going to title this article Hacking a routing component in Jekyll when hosted on GitHub Pages with Markdown, Liquid, and YAML. Obviously, that’s a bit long so I had to shorten it. Anyway, the point doesn’t change: Jekyll lacks some kind of router, and I think I found a not-so-terrible solution to mimic one.
But first things first: I come from a Symfony background, so by router I mean a component that maps URLs to names — a.k.a. routes – so you can safely change a URL without having to crawl your codebase to update all the links heading to the obsolete location.
I am currently working hard on the docs for SassDoc v2 (not released yet, as of this writing). We have quite a bit of content; over 20 pages split across 4 different sections containing many code examples and cross references.
A couple of times during the rewriting, I desired to change a URL. Problem is, when I change a URL I have to update all the links heading to this URL if I don’t want them to be broken. Crawling over 20 pages to make sure all URLs are alright is far from ideal…
This is why we need a routing component. Then we would refer to URLs by name rather than by their path, allowing us to change a path while keeping the name perfectly valid.
So what do we need to make this work? If you are running Jekyll but are not restricted to safe mode (which is unfortunately the case when using GitHub Pages for hosting), you can surely find/build a Ruby plugin to do this. This would be the best solution since this is typically something handled by a server-side language.
Now, if you host your site on GitHub Pages which is more often the case than not with Jekyll, you cannot use plugins nor can you extend Jekyll’s core with custom Ruby code, so you end up hacking a solution with what’s available: Liquid and Markdown.
The main idea is to have a file containing all our routes mapped to actual URLs. Thankfully, Jekyll allows us to define custom global variables through YAML/JSON/CSV files stored in the _data folder, later accessed via site.data.
To add a little syntactic sugar on top, we’ll create Markdown link references that will allow a friendlier syntax – but let’s not go too fast too quickly.
The point of the router is to expose routes (a.k.a. names) mapped to URLs (one to one). It is possible to create YAML/JSON/CSV files in the _data folder of any Jekyll project, so let’s go with a YAML file named routes.yml:
home: "/" about: "/about-us/" faq: "/frequently-asked-questions/" repository: "https://github.com/user/repository"
You may have noted that we are of course not restricted to internal links. We can totally define routes for external URLs to avoid typing them again and again if they tend to show up regularly. Along the same lines, we stopped at 4 routes for our example, but the router could contain hundreds of routes.
Because the file is in _data, we can access its content pretty much anywhere with site.data.
--- layout: default title: "About us" --- <span><!-- Content about us --> </span> Go to our [GitHub repository]({{ site.data.routes.repository }}). Or read the section dedicated to [Frequently Asked Questions]({{ site.data.routes.faq }}).
As you can see, we no longer refer to URLs, but routes instead. This is not magic, it only tells Jekyll to access global variables stored at the given path (e.g. site.data.routes.faq).
Now, if the repository is no longer hosted on GitHub or the “About us” page’s URL is now /about/, not to worry! By updating the router, we make it work without having to come back to our pages to update our links.
At this point, we have a functional router allowing us to change any URL without having to crawl our site to fix broken links. So you can say it is pretty cool already. However, having to type site.data.routes.faq is not very convenient. We could surely make it a bit more elegant!
Yes and no. At first, I thought of building a small route() function accepting a key name and returning the value stored at site.data.routes.
Then I thought of a Markdown feature I never used before: link references. This is how a link is represented in Markdown:
home: "/" about: "/about-us/" faq: "/frequently-asked-questions/" repository: "https://github.com/user/repository"
You can also set the link to head to a reference — which is completely invisible by the way, defined anywhere in the page, like so:
--- layout: default title: "About us" --- <span><!-- Content about us --> </span> Go to our [GitHub repository]({{ site.data.routes.repository }}). Or read the section dedicated to [Frequently Asked Questions]({{ site.data.routes.faq }}).
Note: parentheses are replaced with brackets when using a reference rather than a URL.
This could allow you to have all your links defined in the same place (at the bottom for instance) rather than all over the document. I must say I haven’t used this feature much, but in this case it comes in handy.
The idea is to autogenerate link references from our router so we can use our routes as reference in any file. It turns out to be surprisingly easy to do this in Liquid:
[I am a link](http://link.url/)
By adding this for loop anywhere in the page, this instructs Jekyll to process this as Liquid code, which will then be processed as Markdown references. So for instance, and coming back to our previous example, we could do:
[I am a link][id_reference] [id_reference]: http://link.url
Now we’re talking, right? The only problem is having to include this loop in any page. At first, I thought of adding it in the layout, so it gets automatically added to any page using the relevant layout. The problem is that layouts are not processed as Markdown in Jekyll so the references actually come in visible at the bottom of the DOM. Even worse, they are not usable in our pages since they have not been processed as Markdown… Too bad.
However we can still do something to make it slightly better. We can put this loop in a Liquid partial and include the partial in every page rather than copy-pasting the loop. Say we create a routes.html partial in the _includes folder:
# _includes/route.html {% for route in site.data.routes %} [{{ route[0] }}]: {{ route[1] }} {% endfor %}
And then, in our page:
--- layout: default title: "About us" --- <span><!-- Content about us --> </span> Go to our [GitHub repository][repository]. Or read the section dedicated to [Frequently Asked Questions][faq]. {% for route in site.data.routes %} [{{ route[0] }}]: {{ route[1] }} {% endfor %}
Note: you can include the partial anywhere in the page, not only on top. You could totally put it as the very last line of the file.
That’s it folks, we’ve hacked a little routing component in Jekyll safe-mode. Now what are the drawbacks of this? There are a few minor ones:
Aside from those drawbacks, it’s all good and shiny. What do you think?
The routing component in Jekyll is crucial as it determines the structure of your site’s URLs. It is responsible for mapping each page to a specific URL, which is essential for site navigation and SEO. By hacking the routing component, you can customize your site’s URL structure to suit your specific needs, improving user experience and search engine visibility.
Jekyll allows you to customize your URL structure through the use of permalinks. You can specify a custom permalink in your post’s front matter, which will override the default URL structure. This allows you to create more descriptive and user-friendly URLs, which can improve your site’s SEO and user experience.
Jekyll is a simple, blog-aware, static site generator that’s perfect for personal, project, or organization sites. It’s incredibly flexible and supports custom URL structures, themes, plugins, and more. Plus, because it generates static sites, it’s incredibly fast and secure compared to traditional CMS platforms.
Jekyll supports a wide range of third-party deployment platforms, including GitHub Pages, Netlify, and more. To deploy your site, you’ll need to build it locally, then push the generated static files to your chosen platform. Each platform has its own specific deployment process, so be sure to check their documentation for detailed instructions.
There are many impressive websites built with Jekyll, ranging from personal blogs to large organization sites. Some examples include the official Jekyll website, GitHub Pages, and many more. You can find a showcase of Jekyll websites on the official Jekyll website.
Cloudflare Pages is a JAMstack platform for frontend developers to collaborate and deploy websites. It’s highly compatible with Jekyll and offers a simple, streamlined deployment process. You can connect your GitHub repository to Cloudflare Pages, then it will automatically build and deploy your site whenever you push to your repository.
The official Jekyll website is a great resource for learning more about Jekyll. It offers comprehensive documentation, tutorials, and a showcase of Jekyll websites. Additionally, there are many community resources available, including forums, blogs, and GitHub repositories.
Jekyll supports a wide range of plugins that can add new features and functionality to your site. To add a plugin, you’ll need to install it, then add it to your site’s _config.yml file. Some plugins may also require additional configuration, so be sure to check the plugin’s documentation for detailed instructions.
Jekyll is built with Ruby, but it can be used with other programming languages through the use of plugins and integrations. For example, you can use Jekyll with JavaScript to add dynamic features to your site, or with CSS preprocessors like Sass to streamline your styling process.
Jekyll offers several features that can help optimize your site for SEO. This includes custom URL structures, support for meta tags, and the ability to generate an XML sitemap. Additionally, because Jekyll generates static sites, it’s incredibly fast, which can improve your site’s search engine rankings.
The above is the detailed content of Hacking a Routing Component in Jekyll. For more information, please follow other related articles on the PHP Chinese website!