Instead of hardcoding content in your Jekyll HTML templates, you can use data files to separate content from presentation. This makes updates trivial — edit a JSON file instead of digging through HTML.
_data/content.jsonsite.data.content_data/content.json:
{
"roles": [
{
"icon": "bi bi-journal-text",
"title": "Researcher",
"description": "PhD in Health Data Science, 9+ publications",
"link": "#resume"
},
{
"icon": "bi bi-globe2",
"title": "Consultant",
"description": "FHIR/IHE expert, 13+ countries",
"link": "#resume"
}
]
}
Template:
<div class="row">
{% for role in site.data.content.roles %}
<div class="col-lg-4 col-md-6">
<div class="role-card">
<div class="role-icon"><i class="{{ role.icon }}"></i></div>
<h4>{{ role.title }}</h4>
<p>{{ role.description }}</p>
</div>
</div>
{% endfor %}
</div>
You can filter data inline. For example, showing only current positions:
{% for item in site.data.content.professional %}
{% if item.date contains "Present" %}
<div class="current-role">
<h4>{{ item.position }}</h4>
<p>{{ item.date }}</p>
</div>
{% endif %}
{% endfor %}
This is how you can show concurrent roles side by side — filter for “Present” in the date field and render them in a grid.
Jekyll supports data files in:
_data/content.json_data/content.yml_data/content.csvYAML is the most common in Jekyll projects, but JSON works great if you’re more comfortable with it or want to share the data with JavaScript.
If your JSON contains HTML entities (like &), Jekyll will render them correctly. But if you need actual HTML tags in your data, use the | raw filter or store the content in a separate include file.