# Placeholder Forms

**URL:** https://meta.discourse.org/t/placeholder-forms/113533
**Category:** Theme component
**Tags:** official, placeholder-forms
**Created:** [April 5, 2019, 11:18am UTC](https://meta.discourse.org/t/placeholder-forms/113533 "2019-04-05T11:18:48Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Discourse](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/discourse/32/148734_2.png) [@Discourse](https://meta.discourse.org/u/Discourse)
#### Post date: [April 5, 2019, 11:18am UTC](https://meta.discourse.org/t/placeholder-forms/113533/1 "2019-04-05T11:18:48Z")

</div>

| | | |
| --- | --- | --- |
| :discourse2: | **Summary** | **Placeholder Forms** will let you build dynamic documentation, by creating a form that replaces any occurrence of a =PATTERN= in your post with the value from a text or selectable input field. |
| 👓 | **Preview** | [Preview on Discourse Theme Creator](https://discourse.theme-creator.io/theme/Discourse/placeholder-forms) |
| 🛠 | **Repository Link** | [https://github.com/discourse/discourse-placeholder-theme-component](https://github.com/discourse/discourse-placeholder-theme-component) |
| 📖 | **New to Discourse Themes?** | [Beginner’s guide to using Discourse Themes](https://meta.discourse.org/t/beginners-guide-to-using-discourse-themes/91966) |

Install this theme component

> [@](#):
>
> :discourse2: As this is an #official theme component maintained by the Discourse team, #Support, #Contribute > Bug, #Contribute > UX, and #Contribute > Feature requests can be made in the respective categories here on Meta, and tagged with the appropriate theme component tag. Click on a link below to get one started. 👍
> 
> [❓&nbsp; **Support**](https://meta.discourse.org/new-topic?category_id=6&tags=placeholder-forms "Ask for support on configuring and using Placeholder Forms") [🐛&nbsp; **Bug**](https://meta.discourse.org/new-topic?category_id=1&tags=placeholder-forms "A bug report means something is broken, preventing normal/typical use of the theme component") [👀&nbsp; **UX**](https://meta.discourse.org/new-topic?category_id=9&tags=placeholder-forms "Discussion about the user interface of Placeholder Forms, and how features are presented (including language and UI elements)") [💡&nbsp; **Feature**](https://meta.discourse.org/new-topic?category_id=2&tags=placeholder-forms "Discussion about how existing Placeholder Forms features can be improved or enhanced, and how proposed new features could work")

### Features

Add placeholders to posts in this format:

```plaintext
[wrap=placeholder key=NAME description="Your name"][/wrap]
[wrap=placeholder key=COUNTRY default=US defaults=FR,DE,US,CN,AU,CA][/wrap]

Your email: =NAME=-=COUNTRY=@example.com

```

And this will result in:

 ![14](https://global.discourse-cdn.com/meta/original/3X/b/f/bf9c97efbf63da8a462d1023a684e61bfb524354.png)

This is used in mailing list

Your email: =ZNAME=-=ZCOUNTRY=@example.com

As seen above, text inside the wrapper will be used as a long description.

```plaintext
[wrap=placeholder key=NAME description="Your name"]
This is used in mailing list
[/wrap]

```

## Available keys

- key: The key that should be replaced in your post
- default/defaults: default value(s)
- description: a placeholder text for the input

## Examples

```plaintext
# create a new plugin
rails g plugin =PLUGIN_NAME=
cd plugins/=PLUGIN_NAME=

```

> [@Set up file and image uploads to S3](https://meta.discourse.org/t/setting-up-file-and-image-uploads-to-s3/7229):
>
> So, you want to use S3 to handle image uploads? Here’s the definitive guide, but also see [Configure an S3 compatible object storage provider for uploads](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916) to see how to configure your app.yml. S3 registration Head over to [https://aws.amazon.com/free/](https://aws.amazon.com/free/) and click on [Create a Free Account] During the create account process, make sure you provide payment information, otherwise you won’t be able to use S3. There’s no registration fee, you will only be charged for [what you use](https://aws.amazon.com/s3/pricing/), if you exceed the [AWS …](https://aws.amazon.com/free/)

* * *

We use it to create runbooks, howtos and reusable templates (it will work in code blocks). Please share your use cases!

### Settings

| Translation | Default |
| --- | --- |
| toolbar.builder | Add Placeholder |
| builder.errors.no\_key | A key is required. |
| builder.title | Add Placeholder |
| builder.insert | Insert |
| builder.key.label | Key |
| builder.key.description | The =Key= to be replaced in the post. |
| builder.description.label | Description |
| builder.description.description | Description displayed on input with no value set. |
| builder.values.label | Default value(s) |
| builder.values.description | Optional value(s) for your placeholder, if multiple values are defined, a select will be used. |

  

> :discourse2: **Hosted by us?** Theme components are available to use on our Standard, Business, and Enterprise plans.

> Last edited by @JammyDodger 2024-06-13T22:28:45Z
> 
> > **Check document**
> >
> > Perform check on document:

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [September 24, 2020, 9:10pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/35 "2020-09-24T21:10:36Z")

</div>

The big issue with math handling like this, is that you need to `eval()` and eval is unsafe, so you need to use some lib which provide a safe eval with a limited subset of the real eval. I’m unsure we want all this complexity for such a rare case.

---

<div class="post-metadata">

### Author: ![Benjamin\_D](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/benjamin_d/32/277831_2.png) [@Benjamin\_D](https://meta.discourse.org/u/Benjamin_D)
#### Post date: [July 20, 2021, 3:01pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/38 "2021-07-20T15:01:49Z")

</div>

> [@joffreyjaffeux](#):
>
> Try combining this with the Reply Template theme component!

I tried ! and that would be a neat composer-preview-redux-in-OP kind of thing but.. 😔 I must be missing something, if I understand correctly the Reply Template component takes the raw and looks for “[replacers](https://github.com/discourse/discourse-reply-template-component/blob/5659a23bfa95cfed1343f5740793fca126c5e4b1/javascripts/discourse/initializers/init-discourse-reply-template-component.js.es6#L111)”, but the Placeholder Forms component decorates the cooked?

What I’m trying to do is ease my users into adding some quizz Q&As in a topic, with minimal technical friction, clicks or even key strokes, :heavy-sigh: 🙄

```plaintext
[wrap=placeholder key="question" description="question"][/wrap]
[wrap=placeholder key="réponse" description="réponse"][/wrap]

[wrap=template key="template-spoiler" action="reply" tagsList="#qui, #quand, #où, #comment"]

## Question
=question=
### Réponse
[spoiler]
=réponse=
[/spoiler]
---
*Étiquette(s) ?*
[/wrap]

```

which gives

 ![image](https://global.discourse-cdn.com/meta/original/3X/e/5/e56d35b2cd95f1ad164a1125fa40225493e143fa.png)

so far so good, but unfortunately, the placeholders `=question=` and `=réponse=` are kept in the composer when hitting the template button

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [July 20, 2021, 4:48pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/39 "2021-07-20T16:48:33Z")

</div>

Yes I’m not sure what I was thinking when I wrote this… I probably had a different use case in mind, but can’t remember.

It can’t work this way for sure. I will think a little bit about this… Both theme components were experiments at the time and might deserve better treatment as people have been using it quite frequently.

---

<div class="post-metadata">

### Author: ![Benjamin\_D](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/benjamin_d/32/277831_2.png) [@Benjamin\_D](https://meta.discourse.org/u/Benjamin_D)
#### Post date: [July 21, 2021, 7:42am UTC](https://meta.discourse.org/t/placeholder-forms/113533/40 "2021-07-21T07:42:36Z")

</div>

> [@j.jaffeux](#):
>
> I will think a little bit about this…

Thank you !

![happy lets go GIF by Shalita Grant](https://global.discourse-cdn.com/meta/original/3X/c/8/c83bcbdc53b10a03eb71b70d46611817ea7a8e98.webp)

---

<div class="post-metadata">

### Author: ![Benjamin\_D](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/benjamin_d/32/277831_2.png) [@Benjamin\_D](https://meta.discourse.org/u/Benjamin_D)
#### Post date: [July 23, 2021, 8:09am UTC](https://meta.discourse.org/t/placeholder-forms/113533/41 "2021-07-23T08:09:22Z")

</div>

😁 I don’t know what’s cookin’ in the chef kitchen, but as I usually stuff myself with pistachios or whatnot while waiting, I managed to make it work (for my specific use of course as I’ve almost no idea of what I’m doing, but hey… 😅 )  
[https://github.com/bdecotte/discourse-reply-template-component/commit/68cd32a338a4fd5769a797b00050490d348435ca](https://github.com/bdecotte/discourse-reply-template-component/commit/68cd32a338a4fd5769a797b00050490d348435ca)

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [July 23, 2021, 9:53am UTC](https://meta.discourse.org/t/placeholder-forms/113533/42 "2021-07-23T09:53:08Z")

</div>

Ideally I would like to be able to let admin define their own replacers, but eval is risky (and not even possible with a secure csp) so I’m not sure how I could achieve this…

---

<div class="post-metadata">

### Author: ![sewid](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sewid/32/231694_2.png) [@sewid](https://meta.discourse.org/u/sewid)
#### Post date: [August 20, 2021, 2:41pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/43 "2021-08-20T14:41:27Z")

</div>

First of all - great and really helpful theme component.

But I think I found a bug. If I use a placeholder in a code snippet, that contains backticks (`), it is not working. An example is a SQL code snippet:

```plaintext
DELETE FROM `=TABLENAME=`
WHERE id NOT IN(
        SELECT
            id FROM (
                SELECT
                    id FROM `=TABLENAME=`
                ORDER BY
                    id DESC
                LIMIT 20
) subquery);

```

TABLENAME gets never replaced (if there is a TABLENAME placeholder).

---

<div class="post-metadata">

### Author: ![AquaL1te](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/aqual1te/32/201966_2.png) [@AquaL1te](https://meta.discourse.org/u/AquaL1te)
#### Post date: [March 7, 2022, 6:55pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/44 "2022-03-07T18:55:54Z")

</div>

Would be cool if this also included some Jinja2 like conditions. So that e.g. someone could create a key `red` and map that to the icon 🔴, `orange` would map to 🟠. But I can do without of course, but would’ve been cool to have these test conditions.

---

<div class="post-metadata">

### Author: ![maiki](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maiki/32/233950_2.png) [@maiki](https://meta.discourse.org/u/maiki)
#### Post date: [May 22, 2022, 8:12pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/45 "2022-05-22T20:12:26Z")

</div>

I really love this component. 🤩

* * *

“And you really live by the =NOUN\_1=? What a =ADJECTIVE\_1= life!”

“By it and with it and on it and in it,” said =PERSON\_1=. “It’s brother and sister to me, and aunts, and =NOUN\_2=, and food and drink, and (=ADJECTIVE\_2=) =VERBING\_1=. It’s my =NOUN\_3=, and I don’t want any other. What it hasn’t got is not worth =VERBING\_2=, and what it doesn’t know is not worth =VERBING\_3=. Lord! the =NOUNS\_1= we’ve had together! Whether in winter or summer, spring or autumn, it’s always got its =NOUN\_4= and its =NOUNS\_2=. When the =NOUNS\_3= are on in February, and my =NOUNS\_4= and basement are brimming with =NOUN\_5= that’s no good to me, and the =COLOR\_1= =NOUN\_6= runs by my best =NOUN\_7= window; or again when it all drops =ADVERB\_1= and shows patches of =NOUN\_8= that smells like =FOOD\_1=, and the =NOUNS\_5= and =NOUNS\_6= clog the channels, and I can =VERB\_1= about =MOISTURE= =NOUN\_9= over most of the =NOUN\_10= of it and find fresh =FOOD\_2= to eat, and things =ADJECTIVE\_3= people have dropped out of =NOUNS\_7=!”

* * *

Original taken from [Standard Ebooks version](https://standardebooks.org/ebooks/kenneth-grahame/the-wind-in-the-willows) of [The Wind in the Willows](https://en.wikipedia.org/wiki/The_Wind_in_the_Willows), available to [read online](https://standardebooks.org/ebooks/kenneth-grahame/the-wind-in-the-willows/text/single-page) (search for `By it and with it`).

---

<div class="post-metadata">

### Author: ![Don](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/don/32/228726_2.png) [@Don](https://meta.discourse.org/u/Don)
#### Post date: [September 21, 2023, 11:38am UTC](https://meta.discourse.org/t/placeholder-forms/113533/46 "2023-09-21T11:38:26Z")

</div>

Hello 👋

Thanks for this component ❤ It fits perfectly what I try to achieve now. Actually my first thought was it would be super cool if it can be combine with [Reply Template](https://meta.discourse.org/t/reply-template/162373) component. But unfortunately it’s not possible as the posts above explained it. 😕

* * *

I’ve found a workaround for this to use it as a template, it works with [link to new topics](https://meta.discourse.org/t/create-a-link-to-start-a-new-topic-with-pre-filled-information/28074) and [link to new personal messages](https://meta.discourse.org/t/create-a-link-to-start-a-new-personal-message-with-pre-filled-information/35984).

Here is how made it:

1. Create a Placeholder form (to keep it simple I use the example in OP)

Your email: =NAME=-=COUNTRY=@example.com

* * *

2. Create a link to new topic:  
I set up in the link:

1. category
2. title
3. body

If you want to add empty lines, use `\` so it won’t break the link or to make it invisible you can use `&nbsp;` which will add a space in the new line. It will be a part of the template and makes empty line,

```plaintext
<a href="https://meta.discourse.org/new-topic?category==CATEGORY=&title=This is a topic created by =NAME=&body=Hello :wave:
&nbsp;
This is a test topic... Let's see the placeholder form.
\
Your email: =NAME=-=COUNTRY=@example.com
">Use template as new topic</a>

```

* * *

3. Create a topic preview

> **Selected category**
> 
> =CATEGORY=
> 
> **Topic title**
> 
> This is a topic created by =NAME=
> 
> **Topic body**
> 
> Hello 👋
> 
> This is a test topic… Let’s see the placeholder form.
> 
> Your email: =NAME=-=COUNTRY=@example.com

* * *

4. Create “Use template as new topic” button (in the example above this is a link you can make button from this)

Make a [wrap] element from this text. This makes it available to target it with CSS and style it. I add this to below.

```plaintext
<a href="https://meta.discourse.org/new-topic?category==CATEGORY=&title=This is a topic created by =NAME=&body=Hello :wave:
&nbsp;
This is a test topic... Let's see the placeholder form.
\
Your email: =NAME=-=COUNTRY=@example.com
">[wrap=template-button]Use template as new topic[/wrap]</a>

```

Styling `[wrap=template-button]`  
something like 🔽

Common / CSS

```scss
[data-wrap="template-button"] {
  background: var(--tertiary);
  color: var(--secondary);
  border-radius: var(--d-button-border-radius);
  padding: 0.5em 0.65em;
  transition: background 0.25s;
  &:focus,
  &:hover {
    background: var(--tertiary-hover);
    color: var(--secondary); 
  }
}

```

The template button will looks like this 🔽

![template-button](https://global.discourse-cdn.com/meta/original/4X/0/a/9/0a9cd15be8aa989d2c1e7b85fec8cc3aa70ad51b.gif)

* * *

Demo

[Use template as new topic](https://meta.discourse.org/new-topic?category==CATEGORY=&title=This is a topic created by =NAME=&body=Hello :wave:
 
This is a test topic... Let's see the placeholder form.
\
Your email: =NAME=-=COUNTRY=@example.com)

* * *

I hope this little tutorial will help someone who needs something similar 🙂

Edit: I’ve seted up a category chooser which add the ability to create topic in different categories.

* * *

[Check the raw version of this post…](https://meta.discourse.org/raw/113533/46)

---

<div class="post-metadata">

### Author: ![Lilly](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lilly/32/575047_2.png) [@Lilly](https://meta.discourse.org/u/Lilly)
#### Post date: [September 21, 2023, 12:53pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/47 "2023-09-21T12:53:50Z")

</div>

That’s amazing Don, thank you. This actually suits one of my needs very well 🙂

---

<div class="post-metadata">

### Author: ![jericson](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jericson/32/116215_2.png) [@jericson](https://meta.discourse.org/u/jericson)
#### Post date: [January 4, 2024, 5:03am UTC](https://meta.discourse.org/t/placeholder-forms/113533/48 "2024-01-04T05:03:18Z")

</div>

Something to note is that code blocks sometimes cause problems:

```auto
usermod -aG sudo =USERNAME=

```

In this case, [highlight.js](https://highlightjs.org/) assumes this is Java and converts the codeblock to:

```plaintext
<code class="hljs language-java" data-highlighted="yes">
  usermod -
  <span class="hljs-type">aG</span> 
  <span class="hljs-variable">sudo</span> 
  <span class="hljs-operator">=</span>
  USERNAME=
</code>

```

I’m able to fix it by signaling this is actually a shell command:

````java
    ```shell
    usermod -aG sudo =USERNAME=
    ```

````

That results in:

```shell
usermod -aG sudo =USERNAME=

```

If all else fails, `text` prevents highlight.js from messing with the placeholders.

A more general solution (that Meta Discourse must be using) is to change the `default code lang` setting from `auto` to `plaintext` or somesuch. 😉

* * *

Not that it matters much, but using `java` is a way to avoid having the placeholder expand when you want to write about placeholders.

---

<div class="post-metadata">

### Author: ![putty](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/putty/32/370902_2.png) [@putty](https://meta.discourse.org/u/putty)
#### Post date: [June 5, 2024, 8:35pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/50 "2024-06-05T20:35:07Z")

</div>

Can you check the preview link? It seems to be broken for me.

 ![CleanShot 2024-06-05 at 16.34.16](https://global.discourse-cdn.com/meta/original/4X/1/1/8/118708aa683b557f06ad186b96c28541937d1de4.png)

---

<div class="post-metadata">

### Author: ![NateDhaliwal](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/natedhaliwal/32/313494_2.png) [@NateDhaliwal](https://meta.discourse.org/u/NateDhaliwal)
#### Post date: [June 6, 2024, 9:36am UTC](https://meta.discourse.org/t/placeholder-forms/113533/51 "2024-06-06T09:36:50Z")

</div>

This is an amazing feature, and I can see many uses for it.  
However, in our reply, is it possible to hide the `=(name)=` until the user starts typing in the text box? I feel that users (especially new ones) may not understand its purpose, or, it looks like incorrect formatting.

---

<div class="post-metadata">

### Author: ![JammyDodger](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jammydodger/32/254611_2.png) [@JammyDodger](https://meta.discourse.org/u/JammyDodger)
#### Post date: [June 8, 2024, 10:14am UTC](https://meta.discourse.org/t/placeholder-forms/113533/60 "2024-06-08T10:14:33Z")

</div>

> [@putty](#):
>
> Can you check the preview link? It seems to be broken for me.

I think I’ve got one working again (🤞 🙂)

[https://discourse.theme-creator.io/theme/Discourse/placeholder-forms](https://discourse.theme-creator.io/theme/Discourse/placeholder-forms)

I’ve also added it to [try.discourse.org](http://try.discourse.org) so you can have more of a hands-on play with it. 👍

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [June 8, 2024, 12:20pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/61 "2024-06-08T12:20:31Z")

</div>

Perhaps you could enter a default value that will display instead.

---

<div class="post-metadata">

### Author: ![putty](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/putty/32/370902_2.png) [@putty](https://meta.discourse.org/u/putty)
#### Post date: [June 10, 2024, 1:37pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/62 "2024-06-10T13:37:15Z")

</div>

That worked! Thank you!

---

<div class="post-metadata">

### Author: ![bangarang](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bangarang/32/63023_2.png) [@bangarang](https://meta.discourse.org/u/bangarang)
#### Post date: [August 30, 2024, 3:47pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/63 "2024-08-30T15:47:37Z")

</div>

This workaround doesn’t seem to work anymore.

Are there other options to combine #reply-template and #placeholder-forms?

---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [October 23, 2025, 8:22pm UTC](https://meta.discourse.org/t/placeholder-forms/113533/64 "2025-10-23T20:22:41Z")

</div>

4 posts were split to a new topic: [Links don’t work in placeholder forms](https://meta.discourse.org/t/links-dont-work-in-placeholder-forms/386578)
