# Access Scratch inside Shortcode

**URL:** <https://discourse.gohugo.io/t/access-scratch-inside-shortcode/19148>\
**Category:** support\
**Created:** [June 11, 2019, 6:53pm UTC](https://discourse.gohugo.io/t/access-scratch-inside-shortcode/19148 "2019-06-11T18:53:49Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![dominik.mayer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/dominik.mayer/32/8898_2.png) [@dominik.mayer](https://discourse.gohugo.io/u/dominik.mayer)\
**Post date:** [June 11, 2019, 6:53pm UTC](https://discourse.gohugo.io/t/access-scratch-inside-shortcode/19148/1 "2019-06-11T18:53:49Z")

</div>

I have the following code in my `list.html`:

```auto
{{ range (.Paginate .Pages).Pages.ByPublishDate }}
<div class="section">
    {{.Scratch.Set "ShownInList" true}}
    {{ partial "post.html" . }}
    {{ .Scratch.Delete "ShownInList" }}
</div>
{{ end }}

```

The partial `post.html` renders the content.

In my content I use a shortcode that’s defined as follows:

```auto
{{ if .Page.Scratch.Get "ShownInList" }}
    SOMETHING
{{ else }}
    SOME OTHER THING
{{end}}

```

The shortcode always renders `SOME OTHER THING`. The `.Scratch` is always empty.

(I use the same logic inside `post.html` where it does work.)

The documentation says:

> Note that `.Scratch` from a shortcode will return the shortcode’s `Scratch` , which in most cases is what you want. If you want to store it in the page scoped Scratch, then use `.Page.Scratch` .

What am I missing?

---

<div class="post-metadata">

**Author:** ![dominik.mayer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/dominik.mayer/32/8898_2.png) [@dominik.mayer](https://discourse.gohugo.io/u/dominik.mayer)\
**Post date:** [June 11, 2019, 7:28pm UTC](https://discourse.gohugo.io/t/access-scratch-inside-shortcode/19148/2 "2019-06-11T19:28:39Z")

</div>

When running `hugo` instead of the server the culprit was shown on the command line:

> Error: Error building site: “[…]”: failed to render shortcode “image”: failed to process shortcode: “[…]/layouts/shortcodes/image.html:3:20”: execute of template failed: template: shortcodes/image.html:3:20: executing “shortcodes/image.html” at \<.Date.Day\>: can’t evaluate field Date in type \*hugolib.ShortcodeWithPage

I had tried to access `.Date.Day` instead of `.Page.Date.Day`.

The hugo server hadn’t shown an error. Maybe you could add one to the output there as well?

---

<div class="post-metadata">

**Author:** ![dominik.mayer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/dominik.mayer/32/8898_2.png) [@dominik.mayer](https://discourse.gohugo.io/u/dominik.mayer)\
**Post date:** [June 11, 2019, 7:45pm UTC](https://discourse.gohugo.io/t/access-scratch-inside-shortcode/19148/3 "2019-06-11T19:45:40Z")

</div>

I think there’s a bug hidden somewhere in the shortcuts and `.Scratch` implementation. Without changing anything, just by clicking around on the webpage it stopped working.

I’m using the same logic in the shortcut and in `post.html`.

If I change something in the shortcode it affects the logic in `post.html`. Both **read** the `.Scratch` but don’t alter it.

(I had added `<p>Scratch: {{ .Page.Scratch.Get "ShownInList" }}</p>` at the beginning of the shortcode to help me debug. I removed the `.Page` to see what happens. Then the `.Scratch` logic in `post.html` logic stopped working.)

---

<div class="post-metadata">

**Author:** ![marcia](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/marcia/32/7076_2.png) [@marcia](https://discourse.gohugo.io/u/marcia)\
**Post date:** [June 12, 2019, 7:36pm UTC](https://discourse.gohugo.io/t/access-scratch-inside-shortcode/19148/4 "2019-06-12T19:36:14Z")

</div>

You should be able to use `.Scratch.Set` to set a variable in a template and then use `.Scratch.Get` to access that variable in a shortcode. I’m running 0.55.6 and that works (at least where `.Content` is processed).

Does your call to the shortcode appear below Front Matter? Is “SOME OTHER THING” appearing when you view the page rendered by list.html?

---

<div class="post-metadata">

**Author:** ![dominik.mayer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/dominik.mayer/32/8898_2.png) [@dominik.mayer](https://discourse.gohugo.io/u/dominik.mayer)\
**Post date:** [June 12, 2019, 7:48pm UTC](https://discourse.gohugo.io/t/access-scratch-inside-shortcode/19148/5 "2019-06-12T19:48:54Z")

</div>

Hi @marcia, thanks for your reply.

Yes, the call appears below Front Matter and “SOME OTHER THING” (or the code used in there) is shown on the list page.

I have to store images with the `.md` file. This shortcode is supposed to reference the correct file on both the list and the single page view:

```auto
<figure class="image">
{{ if .Page.Scratch.Get "ShownInList" }}
    {{ $day := .Page.Date.Day }}
    <img src="{{ $day }}/{{.Get 0}}">
{{ else }}
    <img src="{{.Get 0}}">
{{end}}
</figure>

```

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [June 12, 2019, 9:51pm UTC](https://discourse.gohugo.io/t/access-scratch-inside-shortcode/19148/6 "2019-06-12T21:51:08Z")

</div>

@dominik.mayer using scratch to do “inter template” communication is … hard at best.

What happens in your situation, I guess, is that the content (and shortcode) is rendered before .Scratch.Set, but not always. Which is the odd behaviour you see (this is parallel processing in play).

What you want to do isn’t possible, I think. The `.Content` is rendered once (per output format, language).

---

<div class="post-metadata">

**Author:** ![dominik.mayer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/dominik.mayer/32/8898_2.png) [@dominik.mayer](https://discourse.gohugo.io/u/dominik.mayer)\
**Post date:** [June 13, 2019, 6:24am UTC](https://discourse.gohugo.io/t/access-scratch-inside-shortcode/19148/7 "2019-06-13T06:24:30Z")

</div>

Thank you @bep, that explains. I guess it’s the race condition with the shortcode. A similar code inside a partial works consistently:

## `list.html`

```auto
{{ range (.Paginate .Pages).Pages.ByPublishDate }}
<div class="section">
    {{.Scratch.Set "ShownInList" true}}
    {{ partial "post.html" . }}
    {{ .Scratch.Delete "ShownInList" }}
</div>
{{ end }}

```

## `post.html`

```auto
{{ if .Scratch.Get "ShownInList" }}
    {{ $day := printf "%s" (.Date.Format "02") }}
    {{ range .Params.images }}
        <img src="{{ $day }}/{{.}}">
    {{ end }}
{{ else }}
    {{ range .Params.images }}
        <img src="{{.}}">
    {{ end }}
{{end}}

```

Is there any better way of knowing if the current code is rendered on a list or a single page?
