Creating new internal short codes

Folks,

I’ve had a private short-code built on top of an early dev build of Hugo v.13 for a long time. I now find myself in a position where I need to upgrade to the current version of Hugo, but need to keep this short code working. Fairly obviously I have a huge amount of material that relies on this short code.

My new short code, drops the pygements based highlighting approach and replaces it with an alternative highlighter that uses the highlight tool.

With Hugo v13. this was simple to do. I just added the helper/new-highlight.go file and hooked the new short code into the list of internal short codes in tpl/template_embeded.go by adding an entry into the EmbedShortcodes() method.

Now it seems that to do the same thing I need to start hacking both versions of
BlockCode the block code method in helpers/content_render.go.

What I need to do is change the code from this:
func (renderer *HugoHtmlRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) { if viper.GetBool("PygmentsCodeFences") { opts := viper.GetString("PygmentsOptions") str := html.UnescapeString(string(text)) out.WriteString(Highlight(str, lang, opts)) } else { renderer.Renderer.BlockCode(out, text, lang) } }
to this

func (renderer *HugoHtmlRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) { if viper.GetBool("PygmentsCodeFences") { opts := viper.GetString("PygmentsOptions") str := html.UnescapeString(string(text)) out.WriteString(Highlight(str, lang, opts)) // the new bit } if viper.GetBool("UseHighlight") { // use my alternative highlight scheme str := html.UnescapeString(string(text)) out.WriteString(Hilight(str, lang, lexer, lineNumbers)) // see below for an explanation of the extra options } else { renderer.Renderer.BlockCode(out, text, lang) } }

That’s the easy bit. The hard part is going to be more involved.
The problem is the parameters that are being passed about.

My short code and hence the new short codes function takes 4 parameters.

The code to highlight - as a string
The lexer to use - again as a string
The style name - again as a string
Line numbers on/off - also as a string.

Each of these varies on a per call basis. So the information passed to BlockCode is insufficient. Also I cannot set these as “options” in the config for the same reasons.

To give you an idea of the scale of the problem it is not uncommon for me to have a web page containing code snippets of three or more different languages, each with their own highlighting and line number options.

So…Has anyone any idea how to attack this problem? It seems to me that the old approach will no longer work. A simple grep for Highlight as well as my experimentation seems to confirm this.

Owen

Your old approach works fine if you only use highlighting from shortcode and not GitHub style code fences.

I’ve considered this same scenario lately. I wonder what the team (i.e., the Hugo owners) sees as an advantage of having “built-in” short codes or partials. Does this muddy the distinction between the content/data model and the templating layer? Is it also another thing to support?

Would it make more sense for Hugo to focus solely on functions, filters, templates, and easier ways to manage content with complex relationships and then keep common use-case short codes and partials to a library maintained and added to by the Hugo community instead? This is purely spitballin’, but it’s something I’ve been considering since I’d love to someday use Hugo for my organization’s medium-sized publishing sites that seem inseparably wedded to RDBMSs. @bep

What @OwenWaller is doing is a little bit on the outside … As to the “Hugo core”, it should make it easy for people to write the templates and shortcodes they need. We have some obvious internals (youtubue etc.). But for the future it would be cool to have a way of installing “third party addons” including shortcodes.

1 Like

Got it. As always, I appreciate your immediate feedback and explanations @bep. Cheers!

My plans for shortcodes, partials and themes was always to have a repository for them and a mechanism to install them.

Internals is only intended to provide so foundational ones so people could immediately benefit from them.

It is reassuring for a writer to hear his thoughts on this type of technology dovetail with those of a legitimate dev @spf13 @bep Cool. Thanks.

Just to say thanks. The part I was missing originally was that code I needed to change had moved to the tpl/template_funcs.go file. Once I worked that out the process was easy.

If anyone else is trying to write their own short codes you just need to add the new short code to the template in tpl/template_embedded.go. I used the existing short codes as a guide.

Then write a new function for the short code in tpl/template_funcs.go and match your new short code name with the function name by adding an entry to the map in the init function.

If there is enough interest in an alternative highlighter I can think about bundling my change up and submitting it as pull request.

Owen

1 Like

I think there may be user interest … but not enough to spend the manpower to support such a feature.