Trying to print post date in Jekyll fails with undefined method `strftime' - ruby

I've been using Liquid extensions to reformat dates on my Jekyll based site, for example:
<p>{{ post.date | date_to_string }}</p>
This works fine in my index.html page which just takes the five most recent posts and then iterates them post by post. However, this fails when I am trying to render such a date within my _layouts/base.html template.
I have tried:
{{ page.date | date_to_string }}
{{ page.title }} works without issue, and {{ page.date}} renders when I use it without the liquid filter, outputting, for example, 2012-03-12 00:00:00 +0000.
Why does the date_to_string filter fail with the input provided by {{ page.date }}. I get the following error:
Liquid Exception: undefined method `strftime' for nil:NilClass in base
And the build fails. Thanks for any help!

On my site I use
{{ page.date | date: "%d %B %Y" }}
It grabs the date from the markdown file. And is rendered like so:
26 December 2012
See these links for some extra reading:
How does Jekyll date formatting work?
http://liquid.rubyforge.org/classes/Liquid/StandardFilters.html#M000012
EDIT: To answer your question in the comments section:
If you want to use date_to_string you have to call it like this:
{{ site.time | date_to_string }}
There is also {{ site.time | date_to_long_string } which will write the month out in it's full form eg. November not Nov.
Source
https://github.com/mojombo/jekyll/wiki/Liquid-Extensions

Related

Gomplate : bad character U+0022 '-'

I was trying out gomplate and encountered an error.
For context I've defined a template file, test.tmplt, and a datasource file, dev.yaml.
test.tmplt has the following content :
localAPIEndpoint:
advertiseAddress: {{ (datasource "k8s").api-advertise-ip }}
while dev.yaml contains the following :
api-advertise-ip: 192.168.0.1
If I try to fill in the content of test.tmplt using gomplate like so :
gomplate -d k8s=./dev.yaml -f ./test.tmplt -o test.conf
I get the following error :
09:42:44 FTL error="template: ./test.tmplt:2: bad character U+002D '-'"
Seems to me that it does not like the '-' symbol in the template file. Any workaround?Is it the intended behaviour?
Edit 1:
Thanks #icza for the answer which works correctly for the example above. Yet if I modify the yaml file to have nested fields it seems to break down.
For example
dev.yaml :
kubernetes:
api-advertise-ip: 192.168.0.0
test.tmplt :
localAPIEndpoint:
advertiseAddress: {{ index (datasource "k8s") "kubernetes.api-advertise-ip" }}
In this case the output of :
gomplate -d k8s=./dev.yaml -f ./test.tmplt -o test.conf
is :
localAPIEndpoint:
advertiseAddress: <no value>
Your "k8s" data source is a YAML config, and you want to access the api-advertise-ip property of it.
Since api-advertise-ip contains dashes, you can't use the name as-is in the template, because that's a syntax error: the template engine tries to use api as the property name, and the dash after that is a syntax error.
You have to put the property name in quotes that contains dashes: "api-advertise-ip", but this using the . selector is also invalid syntax.
Use the builtin index function to index the YAML datasource with this key:
localAPIEndpoint:
advertiseAddress: {{ index (datasource "k8s") "api-advertise-ip" }}
gomplate uses text/template under the hood, see a working example on the Go Playground.
When using index and you have multiple nested levels, provide each key as an additional parameter to index.
For example:
localAPIEndpoint:
advertiseAddress: {{ index (datasource "k8s") "kubernetes" "api-advertise-ip" }}
Try this one on the Go Playground.
For those landing here for accessing values from Kubernetes secret (with kubectl) whose keys have hyphen - in them, the solution as suggested by #icza is:
kubectl -n <namespace> \
get secret <secret-name> \
-ogo-template='{{ index .data "key-with-hyphens" | base64decode }}'

Unescaped pug attribute not processed by laravel blade

I'm using Laravel Pug https://github.com/BKWLD/laravel-pug, and the file is named *.pug.blade.php. I'm trying to set an attribute value.
| <?php $x = "any"; ?>
div(class!="{{ $x }}")
| {{ $x }}
the output html is
<div class="{{ $x }}">any</div>
Interestingly, in attribute, the php variable is accessed with no < ? php ? > or {{ }} enclosures, just like javascript variables
| <?php $x = "any"; ?>
div(class=$x)
| {{ $x }}
the HTML output
<div class="any">any</div>
Also, the dollar sign can be omitted, and interpolation can be used
| <?php $x = "any"; ?>
div(class = x + "test")
| {{ $x }}
the HTML output
<div class="anytest">any</div>

Jekyll extracting filename from url with Ruby

I'm trying to extract the file name from a url on Jekyll using this ruby snippet:
{% assign filename = page.url.split('/')[-1] | replace: '.html', '.md' %}
If I just use:
{% assign filename = page.url | replace: '.html', '.md' %}
I get back the url with the replaced file type but my .split('/')[-1] doesn't seem to work.
I tried running the following in standalone ruby to ensure my syntax was right, and it returned bird as expected:
"cat/dog/b­ird".split­('/')[-1]
Why doesn't the same syntax work in my Jekyll instance? Is it that page.url isn't a string, or something else?
The problem is mixing ruby code with Liquid tags.
To extract the filename from a url in Jekyll you can use just pure Liquid template filters, using the equivalents of what you tried:
.split­('/') -> | split: '/'
[-1] -> | last
As an example with a custom URL:
{% assign url_example = "cat/dog/bird.html" %}
{% assign filename = url_example | split: '/' | last | replace: '.html', '.md' %}
{{filename}}
outputs:
bird.md

Jekyll says Liquid Exception: invalid byte sequence in US-ASCII in documentation.html

I'm trying to run jekyll build on GitLab CI.
This is my .gitlab-ci.yml:
pages:
script:
- export LC_ALL=en_US.UTF-8
- export LANG=en_US.UTF-8
- gem install jekyll
- jekyll build --destination public
artifacts:
paths:
- public
When the task runs I get this error:
Generating...
Liquid Exception: invalid byte sequence in US-ASCII in documentation.html
jekyll 3.1.2 | Error: invalid byte sequence in US-ASCII
ERROR: Build failed with: exit code 1
More informations
documentation.html is:
---
layout: page
title: Documentation
description: Learn how to create awesome poppers
---
<!-- This page is generated by the grunt doc task of the master branch! Don't edit it! -->
{% markdown documentation.md %}
And documentation.md is a markdown document generated by grunt-jsdoc2md.
This is the markdown plugin I'm using:
=begin
Jekyll tag to include Markdown text from _includes directory preprocessing with Liquid.
Usage:
{% markdown <filename> %}
Dependency:
- kramdown
=end
module Jekyll
class MarkdownTag < Liquid::Tag
def initialize(tag_name, text, tokens)
super
#text = text.strip
end
require "kramdown"
def render(context)
tmpl = File.read File.join Dir.pwd, "_includes", #text
site = context.registers[:site]
tmpl = (Liquid::Template.parse tmpl).render site.site_payload
html = Kramdown::Document.new(tmpl).to_html
end
end
end
Liquid::Template.register_tag('markdown', Jekyll::MarkdownTag)
Attempts
As you see, I've already tried setting LC_ALL and LANG to en_US.UTF-8.
I've also added encoding: utf-8 to my _config.yml but it still doesn't work...
Another attempt was to use #text = text.encode("iso-8859-1").force_encoding("utf-8").strip in the markdown plugin.
Suggestions?
I had the same problem and found this solution, which worked for me.
https://gitlab.com/gitlab-org/gitlab-ce/issues/14983
image: ruby:2.3
before_script:
- apt-get update >/dev/null
- apt-get install -y locales >/dev/null
- echo "en_US UTF-8" > /etc/locale.gen
- locale-gen en_US.UTF-8
- export LANG=en_US.UTF-8
- export LANGUAGE=en_US:en
- export LC_ALL=en_US.UTF-8
I deleted the markdown plugin and used this:
---
layout: page
title: Documentation
description: Learn how to create awesome poppers
---
<!-- This page is generated by the grunt doc task of the master branch! Don't edit it! -->
{% capture documentation %}
{% include documentation.md %}
{% endcapture %}
{{ documentation | markdownify }}
Everything seems working fine now.

How do I access variables under liquid filter argument?

module MyFilter
def all_caps(input)
input.upcase
end
end
Liquid::Template.register_filter(MyFilter)
template = Liquid::Template.parse(" {{ 'hi john' | all_caps }} ")
template.render
# => " HI JOHN "
template = Liquid::Template.parse(" {{ 'hi {{name}}' | all_caps }} ")
template.render('name' => 'john')
# => " ' | all_caps }} "
How do I fix this? No mentions in the official documentation.
Note: I have used all_caps example just for the simplicity. I want to achieve something complex.
I did figure out a way to do that. Would appreciate if there is any other solution.
template = Liquid::Template.parse("{% capture some_text %} Hi, {{name}} {% endcapture %} {{ some_text | all_caps }}")
template.render('name' => 'john')
Hope this helps.

Resources