Is it possible to reuse logic and variables between shortcodes

Greetings. I’m wondering about the extent to which one shortcode can reuse another. In other words, is it possible to make a reusable function that other shortcodes can access and pass variables to?

I don’t think there’s a way to call shortcode from a shortcode, is there? I know shortcodes can be nested, and I think it’s possible to access the variable with .Parent. I tried with a partial, but I struggled to access the variable. From reading around on the forums, it seems execution goes from inner to outer, but I have a muddy mental model about variable context.

For example, the following problem, I found a better solution in using a datafile, but I was wondering whether something like this is generally possible.

Take one file, tcp.html :

<!-- your terms -->
{{ $term := "Transmission Control Protocol" }}
{{ $acronym := "TCP" }}

<!-- reusable boilerplate -->
{{ $count_id := print ( $acronym | lower ) "_count"}}

{{ with .Page.Scratch.Get ( $count_id ) }}
  <abbr title="{{ $term }}">
  {{ $acronym }}</abbr>
{{ else }}
  {{ $term }} ({{ $acronym }})
  {{ .Page.Scratch.Set ( $count_id ) 1 }}
{{ end }}

I’d like to abstract out all the boilerplate into a shared shortcode.
So I could make another file, something like udp.html.

{{ $term := "User Datagram Protocol" }}
{{ $acronym := "UDP" }}

{{< main >}}

I realize that for this particular problem, a data file is a better option (the preceding just turns shortcode files into glorified data files anyway). But it made me wonder about ways to reuse functions.

I think your answer is to call partial templates (which can return values) from the shortcode.

1 Like

Ah! This has brought me very close, but I can’t figure out how to set a scratch pad variable in the partial. I’ve tried both .Scratch.Set and .Page.Scratch.Set. Any ideas where I’m going wrong?

Also, to avoid the XY problem, I’ll state my intention: I want to conditionally format the text based on whether the shortcode was used before. I also thought about .Ordinal but I think that counts all shortcode appearances.

shortcodes/tcp.html :

{{ $term := "Transmission Control Protocol" }}
{{ $acronym := "TCP" }}
{{ partial "acronym.html" (dict "term" $term "acronym" $acronym) }}

partials/acronym.html:

{{ $count_id := print ( .acronym | lower ) "_count"}}

{{ with .Page.Scratch.Get ( $count_id ) }}
  <abbr title="{{ .term }}">
  {{ .acronym }}</abbr>
{{ else }}
  {{ .term }} ({{ .acronym }})
  {{ .Page.Scratch.Set ( $count_id ) 1 }}
{{ end }}

You need to pass the page context in the partial call.

Yes, thanks!

I was able to make a generic solution with the following. Perhaps it could be a little better with with, but the context change confused me. Anyway this does just what I want and it’s easy for me to understand:

Shortcode:

{{ $term := "Transmission Control Protocol" }}
{{ $acronym := "TCP" }}

<!-- reusable boilerplate -->
{{ partial "acronym.html" (dict "term" $term "acronym" $acronym "context" .Page ) }}

partial/acronym.html:

{{ $count_id := print ( .acronym | lower ) "_count"}}

{{ if gt ( .context.Scratch.Get $count_id) 0 }}
  <abbr title="{{ .term }}">{{- .acronym -}}</abbr>
  {{ .Scratch.Get $count_id }}

{{ else }}
  {{ .term }} ({{ .acronym }})
  {{ .context.Scratch.Set ($count_id) 1 }}
{{ end }}

Sorry, but the pedant in me cannot avoid mentioning that TCP is not an acronym, it is an initialism.

Both initialisms and acronyms are abbreviations, the difference is that acronyms can be spoken naturally as a single word, eg: NATO, NASA, scuba, laser, etc.

Initialisms are those that must be spoken as they are spelled, e.g: http, tcp, IMF, WWF, etc.

1 Like

Thanks and no worries, I love such pedantry myself. As a technical communicator I value precision in words :slight_smile:

When I make my blog post about this shortcode, I promise I’ll include a little aside about this acronym-initialism distinction, and probably link to the relevant Google Style Guide topic.

I’m still not sure what I want to call this article/shortcode. My original thought was that something like “Auto-format acronym tooltips” is more approachable and obvious than something with “abbreviation” (or initialism). Maybe I should use abbreviation instead.

1 Like

Great. Glad I didn’t offend :slight_smile: Thanks for the link, I’ve never seen that one before. Good reference.

Personally, I’d use abbreviation. 1:1 mapping to the html element of the same name makes it obvious what it does, and everyone understands the term. Please do post a link to the post when it’s ready, I’d love to read.

1 Like

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