Reputation: 641
I'm using Jekyll, and have stored some information in _data/some_data.yml
, which contains data like this:
---
links:
- http://example.org/some/data
- http://example.org/some/other/data
Another record, _data/more_data.yml
, contains data like this:
---
links: http://example.com
A third record, _data/yet_more_data.yml
, contains data like this:
---
links:
"A title-based link": http://example.net
"Another title-based link": https://example.net/some/other/page
I will be parsing the data sources in the template, like this:
<pre>
{% for a_record in site.data %}
Parsing: {{ a_record[0] }}
Links:
<< PSUDOCODE >>
{% if a_record[1].links is a string %}
* [{{ a_record[1].links }}]({{ a_record[1].links }})
{% elseif a_record[1].links is an array %}
{% for link in a_record[1].links %}
* [{{ link }}]({{ link }}]
{% endfor %}
{% elseif a_record[1].links is a hash %}
{% for link in a_record[1].links %}
* [{{ link[0] }}]({{ link[1] }})
{% endfor %}
{% endif %}
<< /PSUDOCODE >>
- End Record -
{% endfor %}
</pre>
How can I work out if I'm looking at a string, an array or a hash?
I started writing a plugin to support this check, but it's not working out the way I expected - at all!
module Jekyll
module IsAFilter
def is_a_string(value)
if not value.instance_of?(::Hash)
if not value.instance_of?(::Array)
if value.instance_of?(::String)
return true
end
end
end
return false
end
def is_a_hash(value)
if not value.instance_of?(::Array)
if value.instance_of?(::Hash)
return true
end
end
return false
end
def is_an_array(value)
if not value.instance_of?(::Hash)
if value.instance_of?(::Array)
return true
end
end
return false
end
end
end
Liquid::Template.register_filter(Jekyll::IsAFilter)
To use that, I imagined that I could do {% if a_record[1].links | is_a_string %}{{ a_record[1].links }}{% endif %}
but that always renders it as a string, even if it's an array or a hash?
And, before it's suggested, yes, I could say "you must always use the YAML hash format", but once I've finished writing this, I'm going to be handing control of the data to someone else, so I want to be sure that whatever they end up putting in there, it'll work.
Upvotes: 0
Views: 128
Reputation: 641
I had it so close! Thanks to @bashford7's answer, I amended my code to use the form value.is_a? String
, but the problem was actually in my understanding of Jekyll...
I had to use this stanza:
{% assign check_variable = some_variable | some_filter_that_returns_true %}
{% if check_variable %}
USE THIS STANZA - IT WORKS
{% endif %}
Instead of what I assumed I could use, which was this stanza:
{% if some_variable | some_filter_that_returns_true %}
DON'T USE THIS STANZA - IT DOESN'T WORK
{% endif %}
My final plugin, if it's useful, looks like this:
module Jekyll
module IsAFilters
def is_a(value)
return value.inspect
end
def is_a_string(value)
if value.is_a? String
return true
end
return false
end
def is_a_hash(value)
if value.is_a? Hash
return true
end
return false
end
def is_an_array(value)
if value.is_a? Array
return true
end
return false
end
end
end
Liquid::Template.register_filter(Jekyll::IsAFilters)
Upvotes: 0
Reputation: 385
In ruby you can use .is_a? DataType
. E.g.
[1] pry(main)> "hello".is_a? String
=> true
[2] pry(main)> {key: 1}.is_a? Hash
=> true
[3] pry(main)> [1,2,3].is_a? Array
=> true
Upvotes: 1