惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
V
V2EX
Jina AI
Jina AI
爱范儿
爱范儿
M
MIT News - Artificial intelligence
量子位
L
LangChain Blog
Google DeepMind News
Google DeepMind News
酷 壳 – CoolShell
酷 壳 – CoolShell
罗磊的独立博客
腾讯CDC
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
宝玉的分享
宝玉的分享
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
F
Fortinet All Blogs
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss

CloudCannon Blog

Building with AI: Git-based vs headless vs traditional CMS CloudCannon + Astro: performance meets powerful content management Introducing the Astro Component Starter Introducing Jetstream — built on the Astro Component Starter Why we switched to the system font stack Redesigning CloudCannon’s docs with Diátaxis, Lume, and Pagefind Make content editing more visual: upgraded Editable Regions How Configuration Mode makes building editing interfaces easy Your hosting just got an upgrade (and a price cut) Custom testing domains for professional branding Keep your content consistent with input validation Managing multilingual content in CloudCannon Simplify team publishing with conflict resolution and domain tools Open Beta: Publishing Conflict Resolution Getting started with CloudCannon and Astro: Bookshop, components, and live editing Welcome to the CloudCannon Community! Omnichannel delivery is just marketing spin from API-based CMS companies Getting started with CloudCannon and Astro: Snippets and Collections Managing digital assets in CloudCannon: a guide to smart asset storage Understanding CloudCannon's branching workflows and Projects: a complete guide What is a static website? CloudCannon’s 2024 wrapped Getting started with CloudCannon and Astro: WYSIWYG blogging Jamstack vs. WordPress: reasons to make the change The top five static site generators for 2025 (and when to use them!) Free Jekyll themes for 2025: ten great community options Eleventy (11ty) vs. Hugo How to set up WYSIWYG editing with MkDocs Material The rise of static-first websites: why major brands are making the switch Watching your Core Web Vitals on Jamstack
Comparing a Jekyll and Hugo template
2021-11-08 · via CloudCannon Blog

For this showcase, I thought it would be interesting to compare the implementations of a template with both Jekyll and Hugo versions.

Layout Direct link to this section

Let's start with the overarching layout. This is _default.html on the Jekyll site:

<!DOCTYPE html>
<html lang="en-us">

{% include head.html %}

<body>

{% include sidebar.html %}

<div class="content container">
{{ content }}
</div>

</body>
</html>

and baseof.html on the Hugo site:

{{ partial "head.html" . }}
<body class="{{ .Site.Params.themeColor }} {{if .Site.Params.layoutReverse}}layout-reverse{{end}}">
{{ partial "sidebar.html" . }}
<main class="content container">
{{ block "main" . -}}{{- end }}
</main>

{{ if not .Site.IsServer }}
{{ template "_internal/google_analytics.html" . }}
{{ end }}
</body>
</html>

The code is very similar in these layouts. It's interesting seeing the subtle differences between Jekyll and Hugo with includes/partials and content blocks. Hugo adds more options allowing you to set a theme color, reverse the layout and set up Google Analytics.

One subtle difference is the head.html include in Jekyll doesn't include the <html> tag and doctype, whereas the Hugo partial does. I'm a big fan of opening and closing HTML tags in the same file. Untangling nested elements across multiple files is a nightmare.

The post layout is slightly different between the two implementations. In Jekyll we have a related posts section:

---
layout: default
---

<div class="post">
<h1 class="post-title">{{ page.title }}</h1>
<span class="post-date">{{ page.date | date_to_string }}</span>
{{ content }}
</div>

<div class="related">
<h2>Related Posts</h2>
<ul class="related-posts">
{% for post in site.related_posts limit:3 %}
<li>
<h3>
<a href="{{ post.url }}">
{{ post.title }}
<small>{{ post.date | date_to_string }}</small>
</a>
</h3>
</li>
{% endfor %}
</ul>
</div>

Where as in Hugo this has been changed to a Disqus comments section:

{{ define "main" -}}
<div class="post">
<h1>{{ .Title }}</h1>
<time datetime={{ .Date.Format "2006-01-02T15:04:05Z0700" }} class="post-date">{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
{{ .Content }}
</div>

{{ if .Site.DisqusShortname -}}
<h2>Comments</h2>
{{ template "_internal/disqus.html" . }}
{{- end }}
{{- end }}

Post Direct link to this section

The posts on the Hyde site in Jekyll a straightforward: YAML front matter with a body of Markdown.

---
layout: post
title: What's Jekyll?

---

[Jekyll](http://jekyllrb.com) is a static site generator, an open-source tool for creating simple yet powerful websites of all shapes and sizes. From [the project's readme](https://github.com/mojombo/jekyll/blob/master/README.markdown):

> Jekyll is a simple, blog aware, static site generator. It takes a template directory [...] and spits out a complete, static website suitable for serving with Apache or your favorite web server. This is also the engine behind GitHub Pages, which you can use to host your project’s page or blog right here from GitHub.

It's an immensely useful tool and one we encourage you to use here with Hyde.

Find out more by [visiting the project on GitHub](https://github.com/mojombo/jekyll

One minor improvement I'd make here is setting the layout as a default in the _config.yml rather than specifying it on each post.

defaults:
-
scope:
path: ""
type: posts
values:
layout: post

On the Hugo site we don't have any posts, instead we have an archetype - a template to create new posts:

+++
Description = ""
Tags = ["Development", "golang"]
Categories = ["Development", "GoLang"]
menu = "main"
+++

The structure is TOML front matter with an empty body for Markdown. The menu = "main" in the front matter adds the post to the sidebar:

<ul class="sidebar-nav">
<li><a href="{{ .Site.BaseURL }}">Home</a> </li>
{{ range .Site.Menus.main -}}
<li><a href="{{.URL}}"> {{ .Name }} </a></li>
{{- end }}
</ul>

Where as Jekyll iterates over all pages with a layout of "page" for the sidebar.

{% assign pages_list = site.pages %}
{% for node in pages_list %}
{% if node.title != null %}
{% if node.layout == "page" %}
<a class="sidebar-nav-item{% if page.url == node.url %} active{% endif %}" href="{{ node.url }}">{{ node.title }}</a>
{% endif %}
{% endif %}
{% endfor %}

The Hugo site could do with two archetypes, one for a page and one for the post. At the moment, the archetype is in-between. We have posts with tags and categories but no date.

Post list Direct link to this section

On the Jekyll site, the Post list page iterates over the paginated posts and outputs the title, URL, date, and content:

<div class="posts">
{% for post in paginator.posts %}
<div class="post">
<h1 class="post-title">
<a href="{{ post.url }}">
{{ post.title }}
</a>
</h1>

<span class="post-date">{{ post.date | date_to_string }}</span>

{{ post.content }}
</div>
{% endfor %}
</div>

There's also handling of the pagination below the posts.

<div class="pagination">
{% if paginator.next_page %}
<a class="pagination-item older" href="{{ site.baseurl }}page{{paginator.next_page}}">Older</a>
{% else %}
<span class="pagination-item older">Older</span>
{% endif %}
{% if paginator.previous_page %}
{% if paginator.page == 2 %}
<a class="pagination-item newer" href="{{ site.baseurl }}">Newer</a>
{% else %}
<a class="pagination-item newer" href="{{ site.baseurl }}page{{paginator.previous_page}}">Newer</a>
{% endif %}
{% else %}
<span class="pagination-item newer">Newer</span>
{% endif %}
</div>

The Hugo post list page is much more simple. It iterates over all the pages on the site and outputs the title, URL, and summary with a date.

{{ define "main" -}}
<div class="posts">
{{ range .Site.RegularPages -}}
<article class="post">
<h1 class="post-title">
<a href="{{ .Permalink }}">{{ .Title }}</a>
</h1>
<time datetime="{{ .Date.Format "2006-01-02T15:04:05Z0700" }}" class="post-date">{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
{{ .Summary }}
{{ if .Truncated }}
<div class="read-more-link">
<a href="{{ .RelPermalink }}">Read More…</a>
</div>
{{ end }}
</article>
{{- end }}
</div>
{{- end }}

There's still work to do to get the Hugo site into a usage state for a blog. I need to filter this to only posts and populate the date from the post itself.

Summary Direct link to this section

That wraps up the comparison of the Jekyll vs. Hugo Hyde template. It's always interesting to see implementation differences between static site generators. If you have a template or site you'd like a showcase, reach out to us on Twitter.