Inline content from a static file for highlighting in post content

Hi. I am in the process of migrating my web site from WordPress to Hugo. I am looking for a way to inline content from a local static file for highlighting in post content. I am really new to Hugo and still learning everyday.

In my wordpress posts, I used the Crayon Syntax Highlighter plugin in order to insert highlighted code examples. This plugin allowed me to refer to a local file path instead of embedding the actual code within the post itself. In other words, if the code had to be changed, I did not had to edit all posts that referred the file, locate the inline code and make the changes.

I am looking for a way to do something similar with Hugo.

I tried to use a dummy shortcode to read a file and output its content as markdown :

{{
$path := .Get "file" }}{{
$content := readFile $path }}{{
print $content }}

and in my post, I tried multiple ways to call the shortcode:

# Test 1 - code fence with cpp (comments)
```cpp
int a = 0;
{{< inline_static_file file="/static/wp-content/uploads/2015/01/guess.cpp" >}}
string c;
```

# Test 2
```cpp 
int a = 0;
/* {{< inline_static_file file="/static/wp-content/uploads/2015/01/guess.cpp" >}} */
string c;
```

# Test 3
{{< highlight cpp "linenos=table,hl_lines=8 15-17,linenostart=199" >}}
{{< inline_static_file file="/static/wp-content/uploads/2015/01/guess.cpp" >}}
{{< /highlight >}}

# Test 4
```
{{< inline_static_file file="/static/wp-content/uploads/2015/01/guess.cpp" >}}
```

None of the tests above seems to have worked.

  • In test #1, the shortcode did not output anything. I only see the c++ code from the post: int a = 0; and string c;.
  • In tests #2, now the c++ content is printed as a multi-line comment. If i remove the /* */, I end up like in test #1.
  • In test #3 the c++ code seems to have been converted to HTML. The highlight section shows literal &lt; and &#34;. The double quotes were converted to their matching HTML entities as if it was the actual content of guess.cpp.
  • In test #4, I see the content of the file as expected but it is not highlighted as c++. If I add cpp to identify the code as c++, I end up like in test #1 (no content printed).

I think I do not understand Hugo’s parsing pipeline. From my point of view, Hugo reads my post, execute all shortcodes (which outputs markdown content) and then the whole β€œresolved” post is sent as markdown to the theme (or templates) be converted to HTML. From my viewpoint, I would like my shortcode to be similar to a c++ #include directive.

If that helps, I am using hugo v0.87.0-B0C541E4 windows/amd64 and hugo-future-imperfect-slim theme.

I apologize if this question was already asked. I have been struggling with this problem for a while now and my google-fu about this subject (and searching this forum) has not given me any results.

structure

content/article/
└── article-1/
    β”œβ”€β”€ index.md
    └── guess.cpp

layouts/shortcodes/highlight-content.html

{{ highlight (.Page.Resources.GetMatch (.Get 0)).Content (.Get 1) "linenos=table" }}

And call it like this:

{{< highlight-content guess.cpp cpp >}}
1 Like

Hi. Thank you for such a quick answer.

I have tried your proposed solution but I got the following error:

Error: Error building site: "F:\Projets\Blog\end2endzone-hugo\content\blog\article-1\foobar.md:59:1":
failed to render shortcode "highlight-content":
failed to process shortcode:
"F:\Projets\Blog\end2endzone-hugo\layouts\shortcodes\highlight-content.html:1:45":
execute of template failed:
template: shortcodes/highlight-content.html:1:45:
executing "shortcodes/highlight-content.html" at <0>:
nil pointer evaluating resource.Resource.Content

I created test files at the following absolute locations:

  • F:\Projets\Blog\end2endzone-hugo\content\blog\article-1\foobar.md
  • F:\Projets\Blog\end2endzone-hugo\content\blog\article-1\guess.cpp

I think that’s because .Page.Resources.GetMatch (.Get 0) returns null. I simplified the expression to only foo{{ .Page.Resources.GetMatch (.Get 0) }}bar and got foobar as output. I think the shortcode does not find guess.cpp even if foobar.md and guess.cpp are in the same directory. I did not know about Page Resources before. I think I am missing something obvious.

I managed to get it working by modifying the shortcut as:

{{ highlight (readFile (.Get "file")) (.Get "lang") "linenos=table" }}

and calling it with

{{< highlight-content file="/static/wp-content/uploads/2015/01/guess.cpp" lang="cpp" >}}

Thank you. I am grateful for your help. Calling the highlight function in a shortcode have solved my issue. But I still don’t understand why can’t I use something like

# Test 3
{{< highlight cpp "linenos=table,hl_lines=8 15-17,linenostart=199" >}}
{{< inline_static_file file="/static/wp-content/uploads/2015/01/guess.cpp" >}}
{{< /highlight >}}

Could you elaborate more on what I do not understand? Can a shortcode output markdown instead of the final rendered HTML ?

No, you have not.

I described how to organize your content in a Page Bundle:

content/article/
└── article-1/
    β”œβ”€β”€ index.md
    └── guess.cpp

But you chose to do this instead:

content/
└── article/
    β”œβ”€β”€ article-1.md
    └── guess.cpp

The readFile approach is fine, but I encourage you to learn about Page Resources sooner rather than later.

Change layouts/shortcodes/inline_static_file.html to:

{{ readFile (.Get "file") | safeHTML }}

See https://gohugo.io/functions/safehtml

1 Like

Thank you for pointing out what I did wrong. What I tried previously was not a Page Bundle because my file was named foobar.md instead of index.md or _index.md. I tried your first example and I was able to get the expected result.

I am glad that you brought my attention to Page Bundle format. My next posts will be in written as Leaf Bundles. I like the idea of having all resources of a page self contained in the same directory and the code to get access to a resource is much more elegant than my current structure.

Since I migrated from Wordpress using wordpress-to-hugo-exporter, all my posts are stored in the same directory and my static files are arranged in a directory structure like β€œstatic\wp-content\uploads\[year]\[month]\filename.jpg”. Migrating the content to Page Bundles would be a cumbersome process. I might write a script for this particular task at a later time.

Thank you again for your feedback and suggestions. It was really appreciated.

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