Placeholder Forms

: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.
:eyeglasses: Preview Preview on Discourse Theme Creator
:hammer_and_wrench: Repository Link https://github.com/discourse/discourse-placeholder-theme-component
:open_book: New to Discourse Themes? Beginnerā€™s guide to using Discourse Themes

Install this theme component

Features

Add placeholders to posts in this format:

[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:

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.

[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

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

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 documentPerform check on document:
61 Likes

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.

6 Likes

I tried ! and that would be a neat composer-preview-redux-in-OP kind of thing butā€¦ :pensive: I must be missing something, if I understand correctly the Reply Template component takes the raw and looks for ā€œreplacersā€, 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: :roll_eyes:

[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

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

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.

7 Likes

Thank you !

happy lets go GIF by Shalita Grant

3 Likes

:grin: 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ā€¦ :sweat_smile: )

4 Likes

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ā€¦

2 Likes

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:

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).

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 :red_circle:, orange would map to :orange_circle:. But I can do without of course, but wouldā€™ve been cool to have these test conditions.

I really love this component. :star_struck:


ā€œ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 of The Wind in the Willows, available to read online (search for By it and with it).

10 Likes

Hello :wave:

Thanks for this component :heart: 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 component. But unfortunately itā€™s not possible as the posts above explained it. :confused:


Iā€™ve found a workaround for this to use it as a template, it works with link to new topics and link to new personal messages.

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   which will add a space in the new line. It will be a part of the template and makes empty line,

<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 :wave:

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.

<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 :arrow_down_small:

Common / CSS

[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 :arrow_down_small:

template-button


Demo

Use template as new topic


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

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ā€¦

7 Likes

Thatā€™s amazing Don, thank you. This actually suits one of my needs very well :slight_smile:

2 Likes

Something to note is that code blocks sometimes cause problems:

usermod -aG sudo =USERNAME=

In this case, highlight.js assumes this is Java and converts the codeblock to:

<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:

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

That results in:

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. :wink:


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

1 Like

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

CleanShot 2024-06-05 at 16.34.16

1 Like

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.

I think Iā€™ve got one working again (:crossed_fingers: :slight_smile:)

https://discourse.theme-creator.io/theme/Discourse/placeholder-forms

Iā€™ve also added it to try.discourse.org so you can have more of a hands-on play with it. :+1:

1 Like

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

1 Like

That worked! Thank you!

2 Likes

This workaround doesnā€™t seem to work anymore.

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