Reputation: 401
I'm experimenting with building a site using Jekyll for a friend.
I'm trying to transform front matter from files like /_events/2020-02-25-an-event.md
and /_events/2020-02-26-another-event.md
into something that can be easily embedded into the body of various building blocks of content and result in those pages, as viewed by a visitor, including <script type="application/ld+json">...</script>
tags conforming to schema.org event standards.
A file like /_events/2020-02-25-an-event.md
looks like this:
---
layout: event
title: An event
published: true
startdatetime: 2020-02-28
venue: Best Club Ever
---
Members of the events
collection are meant to render as individual viewable URLs and should have a snippet of JavaScript hiding in their rendered output like this:
<script type="application/ld+json">
[
{
"@context" : "http://schema.org",
"@type" : "Event",
"name" : "An event",
"startDate" : "2020-02-28",
"location" : "Best Club Ever blah blah ... have address stuff to work out, still"
}
]
</script>
I got that working by writing /_plugins/event_schema.rb
as follows:
require 'liquid'
module EventSchemaFilters
def do_not_use_me_directly_single_json_curly(input_object)
%Q(
{
"@context" : "http://schema.org",
"@type" : "Event",
"name" : "#{input_object['title']}",
"startDate" : "#{input_object['startdatetime']}",
"location" : "#{input_object['venue']}"
}
)
end
def event_single_schema_script(input_object)
%Q(
<script type="application/ld+json">
[
#{do_not_use_me_directly_single_json_curly(input_object)}
]
</script>
)
end
def event_multiple_schema_script(input_object_array)
%Q(
<script type="application/ld+json">
[
#{input_object_array.map(&method(:do_not_use_me_directly_single_json_curly)).join(',')}
]
</script>
)
end
def event_multiple_schema_script(input_object_array)
%Q(
<script type="application/ld+json">
[
#{input_object_array.map(&method(:do_not_use_me_directly_single_json_curly)).join(',')}
]
</script>
)
end
end
Liquid::Template.register_filter(EventSchemaFilters)
And then by writing /_layouts/event.html
(which looks up to "page" layout, which looks up to "default" layout) as:
---
layout: page
---
{{ page | event_single_schema_script }}
Unfortunately, if I write /index.md
like this, while I get a nice little array of upcoming events, it renders surrounded by <code>
...</code>
tags and shows up in the body of the home page:
---
title: Home Page
layout: default
---
# {{ page.title }}
{{ site.events | event_multiple_schema_script }}
The desire is to have this script be part of the DOM's JavaScript ... not part of the text on the page:
<script type="application/ld+json">
[
{
"@context" : "http://schema.org",
"@type" : "Event",
"name" : "An event",
"startDate" : "2020-02-28",
"location" : "Best Club Ever blah blah ... have address stuff to work out, still"
}
,
{
"@context" : "http://schema.org",
"@type" : "Event",
"name" : "Another event",
"startDate" : "2020-02-27",
"location" : "Less Good Club blah blah ... have address stuff to work out, still"
}
]
</script>
Moving {{ site.events | event_multiple_schema_script }}
to be the contents of /_includes/event_all_schema_script.html
and trying {% include event_all_schema_script.html %}
didn't help at all -- same problem.
Removing the call to {% include event_all_schema_script.html %}
from /index.md
and putting it into /_layouts/default.html
instead does render the way I want it to. But now it's on every page, including pages like https://example.com/events/2020-02-25-an-event/
, which is not what I want. But it does demonstrate that my problem is that I wrote something I can't just "inject" into the markdown of a ... thing ... that's going to become a web page.
Things that also work in /index.md
but aren't what I want to do:
<script>...</script>
code straight into it{% include event_all_schema_script_hardcode.html %}
into it, where /_includes/event_all_schema_script_hardcode.html
is literally just <script>...</script>
text copy-pasted from the output I showed all of you.
I'm open to re-architecting this, by the way. Not attached to the idea of "filtering" things like site.events
, etc. This is just as far as I got in my "hello world."
The only principles I'm really attached to in a final design:
events
collection (so I can get a CMS like Forestry.io or Netlify CMS to play nice with it).<script>...</script>
block should happen in an "independent, insertable component."
/_layouts/homepage.html
that I have to remind a web designer to copy/paste into /_layouts/better_homepage.html
.{% include event_all_schema_script.html %}
somewhere into it or its layout."{% include event_all_schema_script.html %}
, or whatever equivalent people here help me come up with, to work both in the body of pages/posts/collection-markdown and in layouts./_includes/event_all_div.html
and /_includes/event_single_div.html
, and to let them be used anywhere that the web designer sees fit -- in markdown or in a layout.
Any thoughts on how I can improve this attempt at rendering HTML so it will be both layout- and markdown-friendly?
Thanks so much.
Upvotes: 1
Views: 628
Reputation: 52789
I can't reproduce your problem but it certainly comes from the fact that Kramdown understands any line with four spaces indentation or more like a standard code block.
If you don't want to process some parts of your markdown files, you can use nomarkdown
extension like this :
{::nomarkdown}
Any indented line or block
{:/nomarkdown}
Another workaround can be to switch to html files for your events.
Upvotes: 2