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

推荐订阅源

I
InfoQ
S
SegmentFault 最新的问题
N
Netflix TechBlog - Medium
B
Blog
Jina AI
Jina AI
人人都是产品经理
人人都是产品经理
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 聂微东
Last Week in AI
Last Week in AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
V2EX
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
大猫的无限游戏
大猫的无限游戏
U
Unit 42
J
Java Code Geeks
IT之家
IT之家
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
腾讯CDC

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.