Dev Notes

Software Development Resources by David Egan.

JavaScript Variables from Markdown Includes in Jekyll


Jekyll, Liquid, Markdown
David Egan

The problem: Adding JavaScript variables in the document head makes them available to scripts that execute on the page. Building JavaScript variables using Jekyll include tags results in a breaking error due to a sneaky trailing blank line that is rendered to the output HTML. This can be fixed by filtering the output with the strip_newlines liquid filter.

JavaScript Variables

Within Jekyll, we can add variables that have been set in _config.yml or in other data files. This allows us to easily define variables in a central location.

In this case, we are passing variables to a Google map script. These variables will be used to customise map styles, markers and infowindows. The variables could easily be held in a CSV format file to allow easy data entry by non-technical people. The description field for the main info window needs to be properly formatted HTML - so it can’t easily or conveniently be held in a data file field. It should be edited in a markdown file which is then rendered to the page. The reference to this markdown file is held in the data file /_data/map.yml:

latitude: 52.741865
longitude: -8.772812
zoom: 11
height: 548px
main-brand-colour: "#398A8D"
main-marker: assets/images/marker.png
secondary-marker: assets/images/marker-2.png
title: Cozy Cottage
# description refers to a markdown file that will be the source
# for a HTML string included in the JS variable
description: /content/contact/map-description.md

HTML Include

The following file, map.html, is included in the <head> tag conditionally on the page title being contained in an array of map-displaying pages:

<style>#map-canvas { width: 100%; height: {{ site.data.map.height }}; }</style>
{% capture map_description %}{% include {{site.data.map.description }}%}{% endcapture %}
<script>
var cwCentre = {
  latitude:{{ site.data.map.latitude }},
  longitude:{{ site.data.map.longitude }},
  zoom:{{ site.data.map.zoom }},
  mainMarker:"{{ site.baseurl}}/{{ site.data.map.main-marker }}",
  secondaryMarker:"{{ site.baseurl}}/{{ site.data.map.secondary-marker }}",
  mainBrandColour:"{{ site.data.map.main-brand-colour }}",
  title: "{{ site.data.map.title | escape }}",
  description:"{{ map_description | markdownify | strip_newlines }}",
};
console.log(cwCentre);
var markers = [
  {% for location in site.data.map-coords %}
    ['{{ location.name | escape }}',{{ location.latitude }}, {{ location.longitude }}, '{{ location.description | escape }}']{% unless forloop.last %},{% endunless %}
  {% endfor %}
];
</script>
<script src="https://maps.googleapis.com/maps/api/js"></script>

Strip Newlines

If you don’t add the strip_newlines filter to the markdownified output, the JavaScript variable will have an additional newline. It will look like this in the output HTML:

<script>
var cwCentre = {
  latitude:52.741865,
  longitude:-8.772812,
  zoom:11,
  mainMarker:"/cozy-cottage/_site/assets/images/marker.png",
  secondaryMarker:"/cozy-cottage/_site/assets/images/marker-2.png",
  mainBrandColour:"#398A8D",
  title: "Cozy Cottage",
  description:"<p>Test content</p>
",
};
console.log(cwCentre);
...
</script>

This will trigger an error, due to the bogus character at the end of the line.

You’ll see the error: ‘Uncaught SyntaxError: Unexpected token ILLEGAL’ in the browser console and the script will fail.

The strip_newlines filter sorts this out.

References


comments powered by Disqus