How can I write a Jekyll plugin that modifies the `site` object? - ruby

I want to write a Jekyll plugin that modifies the site object. The site object is available throughout the Jekyll build process. In Jekyll, the most direct way to add an attribute to it is to define it in the _config.yml file. That works in some cases, but I need to take it a step further.
The reason I am asking this question is because I need to do more than I can do in the context of a YAML file. I want to add a method to the site object. I assumed I'd only need to add the method to the Site class, but it isn't working.
Non-working plugin:
module Jekyll
class Site
def foo
"foo"
end
end
end
I assumed from reading the Jekyll source and from how Ruby classes can be extended that the site object in Jekyll would have the new foo method, but it doesn't. For reference, here is the Site Class in the Jekyll source code.
This is as much a question required because of my poor ability to read the RUby code that Jekyll is constructed in as it is a question about Jekyll itself.

Maybe you can do it without a plugin. Inspired by Jekyll Bootstrap you can craft a global variable to target your assets folder.
_config.yml
# can be '' or '/repositoryName'
baseurl: /repositoryName
ASSET_PATH : /assets
_layouts/default.html
---
front mater ...
---
{% capture ASSET_PATH %}{{ site.baseurl }}{{ ASSET_PATH }}{% endcapture %}
Then call assets from post or page :
<link href="{{ ASSET_PATH }}/bootstrap/css/bootstrap.min.css" rel="stylesheet">
or
![img title]({{ ASSET_PATH }}/img/toto.jpg)

Related

Folder _data in theme directory does not get the values

I'm making a Jekyll theme using the command jekyll new-theme mytheme. I want to add translations to this theme, so I created the file _data/translations.yml into the root directory. This is its content:
---
en:
post: "Post"
es:
post: "Artículo"
I get the information with this expressions:
{% assign t = site.data.translations %}
{{ t[site.lang]['post'] }}
This setup only works if I move the _data/translations.yml file to my Jekyll website directory, created through the command jekyll new mysite.
Are the data files out of themes territory? Should I place this yml file in another directory? If it's not possible to use it in the themes territory, I would like to set a default value: how can I achieve this?
Thanks in advance.
As of Jekyll 4.0, yes, data files inside a theme-gem are not read.
You'll need to use a plugin named jekyll-data (authored by me).
If you plan to publish the theme for other users, I recommend adding the plugin as a runtime dependency in the theme's gemspec. Otherwise, simply adding the plugin to the :jekyll_plugins group in the site's Gemfile will suffice.

Render markdown from a yaml multiline string in a Jekyll data file

When using Jekyll data files I would like to store a formatted description, primarily to that I can have links in it. It works with HTML.
- name: Project name
description: >
I want to include a link
That renders properly in the generated page when included with {{ project.description }}.
Can I use markdown instead of HTML? I would prefer to do this:
- name: Project name
description: >
I want to include a [link](http://foobar.com)
Turns out Liquid supports filters, but doesn't have one for processing markdown. Thankfully Jekyll adds it's own set of handy filters which includes markdownify so now I can do this:
{{ project.description | markdownify }}

Can I use the octopress image tag with jekyll-assets asset_path?

If it's possible, I'd like to use the Octopress image tag on images that are served using jekyll-assets.
This works
<img src="{% asset_path image.jpg %}" alt="foo" />
but I'd prefer something like this
{% img asset_path image.jpg 'foo' %}
which gives an error:
Error processing input, expected syntax: {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | “title text” [“alt text”]] %}
Is there a way to get the syntax right, passing the result of asset_path to img? I expect the answer is obvious, but I'm new to Liquid and Jekyll.
I am using the latest stable release of octopress, which depends on jekyll 0.12.1. I am using jekyll-assets 0.4.2, which is the latest version that supports jekyll < 1.0.

How to url encode in jekyll liquid?

I have problem that categories are not url encoded when I use german words with Umlauts (e.g. ä, ü). I tried the cgi_escape that Liquid seems to offer, but success with the following code:
<strong>Kategorien</strong><br/>
{% for category in site.categories do %}
<small>{{ category[0] }} <br/>
</small>
{% endfor %}
Can anyone help?
Using cgi_escape doesn't work correctly for categories with spaces. Links were generated as /category/the+category instead of /category/the%20category.
The solution I ended up using was from this blog post:
# _plugins/url_encode.rb
require 'liquid'
require 'uri'
# Percent encoding for URI conforming to RFC 3986.
# Ref: http://tools.ietf.org/html/rfc3986#page-12
module URLEncoding
def url_encode(url)
return URI.escape(url, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
end
end
Liquid::Template.register_filter(URLEncoding)
A plus is a literal plus anywhere but in the query portion of the URL, where it represents a space. Good URL encoding reference (archive.org mirror).
This can then be used in a layout or anywhere else:
<a href="{{ site.category_dir }}/{{ category | url_encode }}">
#Peterb, have you upgraded to the latest version of Jekyll? The current 1.0x version supports UTF-8 and handles URLs like this much better.
You can install the latest version by running this from your Terminal command line:
$ [sudo] gem install jekyll --pre
This GitHub Issue post will shed more light on the issue:
https://github.com/mojombo/jekyll/issues/960

How can I debug plugins that are being silently ignored?

Newcomer to Jekyll here (previously on Hyde).
Ruby files placed in the _plugins/ directory are apparently silently ignored.
I am using version 0.11.2 of Jekyll, with ruby 1.8.7 on Ubuntu 12.04.
Should an extra config parameter be added to load these plugins? The doc doesn't say so - the sane default should be to look into _plugins, and they should be required automatically. How can one debug the loading of Jekyll plugins?
For my instance of jekyll (also 0.11.2, but with ruby 1.9.2p290 on a Mac), I don't have to add any extra configuration, but you can try adding the following line to your top level "_config.yml" file.
plugins: _plugins
or, possibly,
plugins: ./_plugins
The simplest way to test that your plugins are working is to remove all of them except for one that you know will work. I've put together the following which works as expected on my install.
Create a new file in the root of your jekyll source directory called "plugin_test.md" with the following contents:
---
layout: default
title: Plugin Test
---
the quick brown fox jumps over the lazy dog.
Testing plugin output of '_plugins/testplugin.rb': {% testplugin %}
Note that you may need to change "layout: default" to whatever you are actually using.
Create a new file at "_plugins/testplugin.rb" with the following contents:
module Jekyll
class TestPlugin < Liquid::Tag
def render(context)
"It's Working!"
end
end
end
Liquid::Template.register_tag('testplugin', Jekyll::TestPlugin)
Run jekyll on your source dir.
All that testplugin.rb does is replace instances of the liquid tag {% testplugin %} with the text "It's Working!". If your plugins are triggering, you'll see the output
Testing plugin output of '_plugins/testplugin.rb': It's Working!"
on the page "plugin_test.html" at your output site root. If you see:
Testing plugin output of '_plugins/testplugin.rb':
that means that the plugin didn't trigger. If you run into that, I think it's a sign that something is pretty out of whack and would advise reinstalling jekyll.
I know I'm little bit late but for others who still come across this question I would like to add my resolution:
Restart the server to get the newly added plugin working. So stop jekyll serve (Ctrl C) and restart it again with jekyll serve.

Resources