Migrating from Jekyll to Hugo - Looking for equivalent of 'capture' for reusable content

We are migrating our website from Jekyll to Hugo and we are thoroughly loving the Hugo experience so far. The only challenge we are facing is finding an equivalent way in Hugo to reuse content across multiple pages like we did with capture in Jekyll.

In our Jekyll site, we have pages like tutorials/get-started/android.md, tutorials/get-started/ios.md, and tutorials/get-started/javascript.md that all share a lot of the same content in tutorials/get-started/tutorial.md. You can view a live example from our website here

To reuse the shared content, we did:

In android.md

{% capture init_sample %}
  // android code 
{% endcapture %}

{% capture message_sample %}
  // more android code
{% endcapture %}

{% include_relative tutorial.md %}

and in, tutorial.md

{{init_sample}}
...
{{message_sample}}

This allowed us to keep the common tutorial content in one place and wrap it with platform specific code examples in the individual files (android.md, ios.md, etc).

We have applied this pattern in various sections of the website and trying to adapt the same approach to Hugo. We’ve attempted to use ‘define’ and ‘template’ as direct replacements for ‘capture’ and ‘include_relative,’ but it appears that directly incorporating them into the Markdown files may not be feasible (please correct us if we’re wrong, as we are still new to Hugo).

Any help is appreciated! Looking forward to leveraging Hugo more for our docs.

One of the reasons that Hugo renders sites so quickly is parallel processing; it renders multiple pages simultaneously. With that in mind, capturing content on one page to use in another can be tricky, and in some cases creates a chicken/egg scenario. I advise against it.

On the Hugo documentation site we have a number of “_common” directories that contain markdown snippets. These common snippets are included in pages throughout the site as needed via an “include” shortcode.

Here’s an example:

git clone --single-branch -b hugo-forum-topic-47192 https://github.com/jmooring/hugo-testing hugo-forum-topic-47192
cd hugo-forum-topic-47192
hugo server

And here’s an example from the Hugo documentation site:

https://github.com/gohugoio/hugoDocs/tree/master/content/en/functions/_common

Thank you for the sample code. However, there seems to be a misunderstanding, possibly I didn’t explain clearly what we are trying to achieve in my first post.

The include approach you suggested would insert the same content across all files. Instead, what we need is more like subclass overriding from object-oriented programming - invoking the same tutorial.md template from different parent markdown files, but allowing it to output customized content.

For example, this code in the tutorial.md:

{{message_sample}}

When tutorial.md included from android.md, should display Android code for sending a message. When included from ios.md, it should show iOS code instead. Similarly for other snippers like {{video_call_sample}, {{voice_call_sample}}, etc.

To illustrate, here is the same live example done using Jekyll and now we are trying to achieve using Hugo: Get Started | Android | Mesibo Documentation

Essentially, we need to reuse tutorial.md in multiple platform docs but allow snippets like {{message_sample}} to be overridden by the parent document to output platform-specific code.

Please let me know if this helps explain what we are trying to achieve or if you need any clarification. I appreciate you taking the time to assist!

I’ve added “capture” and “retrieve” shortcodes to the previous example. Please pull changes and test again.

It worked. I really appreciate all your help with this - thanks a lot!

I have one last question.

I’m able to include tutorial.md properly if it’s in /_common or a root layout folder. However, when I keep it inside tutorials/get-started/, Hugo tries to parse it upfront before the include, causing errors like:

ERROR The "retrieve" shortcode was unable to retrieve the "message_sample" capture key

I also tried making a folder tutorials/get-started/_includes and tried to include it as

{{< include-path "_includes/tutorial.md" >}}

where include-path is a modified shortcode to take the relative path. However, Hugo still parses _includes/tutorial.md prematurely before it is included.

Is there any way to prevent Hugo from parsing tutorial.md early when it’s inside the tutorials/get-started/ folder or a subdirectory? My goal is to keep it alongside the including pages rather than moving it to the root.

I really appreciate any suggestions you may have! Thank you again for all the help.

I would preface the file name with an underscore to visually indicate that the page will not be published:

content/
├── tutorials/
│   └── get-started/
│       ├── _index.md
│       ├── _tutorial.md
│       ├── android.md
│       └── ios.md
└── _index.md

Then set the build options in front matter:

+++
title = 'Tutorial'
[_build]
list = 'never'
render = 'never'
+++

I’ve updated the example site. Please pull changes and test again. Note that I have cleaned up the shortcodes, and changed the shortcode call notation from {{% %}} to {{< >}}. At this point I think the example is solid.

One caveat… headings or footnotes that are either “captured” or “included” will not contribute to the .TableOfContents or footnotes on the rendered page.

2 Likes

It works.

Thank you so much for your help, our team and I deeply appreciate your help.

2 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.