Build a Go Playground Custom Hugo Shortcode
Tags: go, hugo, blog
Published: 2020-05-26 04:03:04

---
title: Build a Go Playground Custom Hugo Shortcode
published: true
description: Learn to build a custom Hugo shortcode that builds off of the built-in highlight shortcode in order to allow users more interaction with your code in the Go Playground sandbox. 
tags: golang, go, hugo, blog
---

Note: this article was originally published on [my site](https://lanie.dev/tech/opensource/). 

When I started with Hugo, I began my blog with a prefabricated template. In my opinion, this is the best option if you want to start creating things to put on your site. Unfortunately for me, I still fell into this hole when I wanted to create a way for users to open my code up in the [Go Playground](https://play.golang.org/) and run it for themselves when I discovered the functionality wasn't prexisting in the built-in [highlight shortcode](https://gohugo.io/content-management/syntax-highlighting/). 

I hoped this would be similar to how the [Go By Example](https://gobyexample.com/interfaces) site implements theirs. After asking Go Playground if I could reference the playground on my site (they specifically tell you to ask on the site and please also do so if you want to use this for your own site), I went about hacking myself an addition to the already-present highlight shortcode. For those unfamiliar, the highlight shortcode provides syntax highlighting to Hugo sites in a variety of themes, a method to copy the code, as well as other features. 

If I can be honest, the most challenging part about this was figuring out how to use CSS again, since it's been so long since I was involved with it beyond seeing if I could get past a paywall in the inspector tools. Given that I knew this to be the case, I started writing the shortcode that would allow me to ignore my shortcomings with CSS, and focus on my shortcomings with understanding how custom shortcodes are implemented. 

The reason I wanted this to be a shortcode rather than a partial because the description of partial was exactly what I was looking for -- a small, reusable bit of code that lived inside of my content. I needed to insert it directly into the markdown file I was writing, because it needed the URL I would give it to tell it which Go Playground URL to redirect to. I created the shortcode under the `/layouts/shortcodes` path, and named it `goplay.html` because the task at least was evident.

In practice, the execution of the shortcode was simple. 

```html
<div class="run">
	<form action="http://play.golang.org/p/{{.Get "url"}}" target="_blank" >
    <input type="submit" value="Run" class="goplay-btn" />
	</form>
</div>
```

However, if you don't understand shortcodes immediately, know that I was exactly there when starting this. Above, you can see that the second line is grabbing a string `"url"` with the built-in `.Get` function that comes along with Hugo templating. I can pass the URL into the markdown file using the following syntax: `{{ "{{ goplay url=abcde " }}}}`, where abcde is the end of the url that denotes a unique saved playground. I chose to use a form, rather than a button, because I didn't see a way for a button to reference a .URL and open a new tab right away. It's probably possible: this was just the way I knew how to do it. The target is set to `"_blank"` so that it opens in a new tab, rather than diverting from the current page. 

You'll also notice that the class for the overarching div is `"run"`, and the class for the type `submit` input is `"goplay-btn"`. I created another file under `static/css` called `goplay.css`. I inserted the following into this file:

```css
.run{
    background:#2c3e50;
    display: flex;
    justify-content: flex-end;
    padding-top: 7px;
    padding-bottom: 7px;
    padding-right: 7px;
}
```

This is the parent container for my button, and will match the color of the highlight code for my specific theme (Dracula) while completely filling the space, as the built-in `highlight` shortcode does. I use the word "button" loosely here, as it's a form element, not a button element. The padding gives the internal child element a little bit of room so it's not smushed against the bottom-right corner. You'll also notice that I used flex-box. 

```css
.goplay-btn {
  bottom: 7px;
  right: 7px;
  border: 0;
  border-radius: 4px;
  padding: 1px;
  font-size: .75em;
  line-height: 1.8;
  background-color: #777;
  opacity: .6;
  min-width: 55px;
  text-align: center;
}

.goplay-btn:hover {
  opacity: .45;
}
```

Above, the `goplay-btn` class is in charge of styling my actual button. I moved the internal text around a bit, and changed the background color to match the `copy` button in the hightlight shortcode. I also changed the opacity to match the other shortcode's. I was able to grab a few of the attributes, such as font-size from inspecting the copy button in hugo's highlight shortcode docs, since it's open source. I change the opacity on hover to mimic a button element's natural tendency to do so -- this is completely a hack. 

```css
.chroma { margin-bottom: 0px; }
```

The final key that stumped me a bit is this piece of CSS that I added to the same `goplay.css` file. Previous to adding this, there was a very ugly space between the hightlight shortcode, and the custom shortcode, which was there automatically within my base theme's (Hermit) template. Because the extra space was caused by the `highlight` shortcode's parent container, I couldn't do anything to my custom shortcode to eliminate this extra space. By targeting the `chroma` class in this file, we'll be able to override the bottom margin, and successfully remove the space. The paragraphs in the markdown file seem to have their own spacing, so I haven't noticed any negative consequences to overriding this attribute on the `chroma` class, but there's probably a cleaner way to do this. 

After this code is implemented, you'll be able to link out to the Go Playground by inserting `{{ "{{ goplay url=abcde " }}}}` into the markdown file directly under the closing tag for your highlight shortcode.

Below you can see the finished code!

![snippet of code with "play" button present as example of finished code](https://dev-to-uploads.s3.amazonaws.com/i/4cmq0ute6j8m5h0f499x.png)

This also happens to be my first contribution to the open source community! I've pushed a repo with all this code to my [github profile](https://github.com/laniehei/goplay), and you are free to use on your personal site.