Custom Wizard Plugin


Hi @Angus,

I think I’ll use this plugin as it gives more options to add some nice features in the future (ie. asking for feedback and record it in a category for Staff only and more…)

Something I cannot figure out is how to add a date to a field (I guess to a Custom Field in Actions).
Say I want to send newsletters for a year, I would create a Profile Field “send me newsletter for 12 months” and record the acceptance date so I can stop sending it 12 months from that date. How can I record the date when this option has been accepted?


(Jaron Easterbrook) #208

@gingerman I don’t suppose you found a way to implement this? I have the same use case: different membership levels based on the answers to data completed in the sign-up process.

Since I’m sending out lots of invites, it would be great if there wasn’t a need for a static website, but I’ll take what I can get.



OK so after pressing at the same time volume down and the power button on Android to obtain a screenshot…

Here you can see that the location selection box overflows the wizard box. Noted that this is on mobile but I saw an occurrence on desktop as well with lots of results. (Try “Les Halles”, “Paris”)

I guess it’s fine for the mobile version of the wizard to scroll, and adding an overflow-y somewhere should fix the problem on desktop.


This is unrelated to my previous post: a user with Internet Explorer (does that still exist?) reports that the wizard is not showing up:

The user tried to access the wizard while being logged out, then retried after he logged in, to obtain the above result: maybe some cache? I tried to reproduce with Firefox to no avail.

Meanwhile, I found that returning to the wizard after closing it automatically comes back to the last visited step. Is there a way to force coming back to the first step? Even if there’s already data there, it might be useful to review it and click ‘next’.



I created this as a sample: to confirm that users are over 16. I have noticed that the Custom User Fields appear like this:

but when I use the wizard, populates them like this:


Is there a way to make it say “true” of “yes”? I have had to explain a few times what the “t” means…

Also, if I wanted to show the date of when it has been accepted (for other fields), what else I would have to add to the wizard? This is the set up:

I would really appreciate some help as I am stuck.

I know there is the Submissions area where I can see all submissions but I would like to show the date in the user Admin Profile.

Could I access the Submission list from the database? I looked with DataExplorer but could not find it. It’d be handy to be able to retrieve a list of the submissions.


(Christoph) #212

I just realized that if the wizard is set to trigger for all new sign-ups, it will probably trigger regardless of whether people are signing up via an invite link or via “ordinary” sign up, right?

At least in my use case, that is likely to lead to some confusion so I’d like to be able to distinguish between wizards for both types of sign-up… :grimacing:


I think that’s what the translation key is for. You could try setting it to the translation key for true or yes.

Sorry I can’t help you on your other question.


Thanks @hellekin

for what I can see, the translation keys affect only lables, such as the title of the Steps set and the lable of the Fields used, still adding only a “t” .

I’ll keep experimenting with this, maybe others have experience with this or the date field.

All the best.

(Angus McLeod) #215

Well, every record in the db has a created_at date. So you use that. But there isn’t an easy way to surface this in the Admin UI atm as far as I know.

@gingerman @jaron Looking at this again, it should be possible?

The ability to return back to the correct wizard context after registering as a new user is critical in the above usecases for better user experience and conversions.

Enable the “After Signup” setting and all new users will get kicked into the wizard.

Try setting this up and let me know what specifically you’re missing.

This is actually connected to an issue with Discourse core CSS. I’ve submitted a PR:

Could you check if there are any relevant console logs for the IE user?

(IE and MySpace?? Is this guy a time traveller from 2005?)

hm yeah. I’ll take a look at this on the weekend.

t is the way that postgres represents boolean values. Core Discourse stores “Checkbox” values (which you’re using here) as strings, which is why it shows up as a “true” / “false” string in the Admin UI.

I could store those values as strings as well, but arguably “Checkbox” user fields should be typecast to boolean in core Discourse and then the display in Admin should convert true / false into “True” / “False”. @david What do you think?


Could you explain the use case a bit more?


Hay, let me reproduce my comment there: min-height: none is invalid. You should leave it to min-height: auto, since it’s only the max-height: none that we need.

edit: and… This is merged and fixed! Thank you! :heart:

(DaveK) #217

Hey this looks like a great plugin. Does the wizard also handle image uploads? And can it post the topic in a staff-only area?

(Danny Goodall) #218

Hi @angus, great plugin - as usual!

I think I’ve come across a bug - or at least an inconsistency, and I have a feature request.

tl;dr Bug? - using the CustomWizard::Builder.add_step_handler() feature with a wizard that has a dropdown doesn’t appear to send a value through for the first (default) option in the dropdown. Once the default value is changed, other dropdown values work. Feature request - Can we have support for Datetime fields?


Not essential to reproduce the bug - just sharing the background as I think it’s an interesting use of Discourse.


I work in a school with kids that have social, emotional and mental health challenges. As a staff, we need a way to stay in touch and to discuss important issues relating to the children. I am obviously pushing Discourse for this purpose and so far it has been well received.

In carrying out our work we have a number of paper-based systems that record details of the children’s behaviour and I am investigating if I can use Discourse and the polls feature to replace the very inefficient paper systems. I have a meeting with my boss on Tuesday to do a demo and try to win her over.

One of these paper systems is what we call the Points Card where the child can earn a maximum of 21 points during the day across 7 sessions against 3 categories of behaviour - work, language and safety 3 x 7 = 21.

These 7 sessions are chronologically contiguous, start at 8:15 in the morning and run to 3 pm. After each session, the adult that has worked with the child decides how many (if any) points (Work, Language, Safety) the child has earned.

We manually record these points on paper (on a Points Card, duh!) and then we write a small narrative in a book for context - who was the teacher?, what was the subject?, was there a consequence for poor behaviour?, etc.

I have modelled this in Discourse as follows.

We have a parent category called GG Points.

Inside this category, there are 11 subcategories - one for each SEMH child we work with. The categories are named after the child.

I have enabled events from your Event Plugin in these categories so I can get an Agenda or Calendar for each child. Each topic within these categories is also marked to automatically close after 24 hours.

Inside the child category, I then create 7 topics - one for each time period during the day that the child can earn points for.

Within each of these topics I create 4 Discourse polls to record the points for that session:

And finally, at the end of the thread, staff members are then able to add any additional narrative to help us understand the behaviour by replying and adding posts to the topic.

I’ve written a small routine in (stand-alone) Ruby using the API gem that creates the categories and posts. The problem I then faced was how to kick-off the routine for a given date or date range.

I initially thought I would run a batch script that would create the points card for the 11 children for that day. This seemed inefficient so I wanted to be able to specify each individual child and a date range so looked at trying to develop a plugin but Ember and the front-end UI are a little beyond my current skills and available time.

So, as these points card topics need to be created every day, I had decided that I would create a recurring sidekiq job, convert my stand-alone code to a headless (no UI) plugin that would be run once a day and sit back and relax.

But then I saw that your Custom Wizard Plugin allows us to run plugin code after each step or when the wizard is submitted. I decided that your Wizard can be my UI. I will also need a UI solution when I start reporting on this data and it feels like this could be the perfect solution.

Anyway, back to that bug and feature request.


There could be two bugs or it may be one that represents itself in two places (or no bugs and I could be misunderstanding something!).

Bug? 1

So I’ve created a wizard with one step step_1 and with a single field children_to_create which is a dropdown with custom choices.

I have a plugin shell (generated by the rails g plugin SchoolPoints) called SchoolPoints with the following code in plugin.rb within the class SchoolPoints::ActionsController < ::ApplicationController section.

  class SchoolPoints::ActionsController < ::ApplicationController
    requires_plugin PLUGIN_NAME

    before_action :ensure_logged_in

    def list
      render json: success_json

    CustomWizard::Builder.add_step_handler('select_children') do |builder|"************************************")"ARRIVED IN THE PLUGIN")"************************************")"************************************")
      # your logic.

If I go to the URL for the wizard and, without doing anything and with the “All Children” default option of the pulldown highlighted, I press “Done”, the wizard hits my plugin code and leaves this in the logs.

I, [2018-10-25T20:21:13.588540 #25377]  INFO -- : ************************************
I, [2018-10-25T20:21:13.590755 #25377]  INFO -- : ARRIVED IN THE PLUGIN
I, [2018-10-25T20:21:13.593568 #25377]  INFO -- : ************************************
I, [2018-10-25T20:22:34.089509 #25377]  INFO -- : {"children_to_create"=>""}

i.e. there is no value for the children_to_create key in builder.updater.fields.

I was expecting to see the value of “All Children

However, if I change the value of the dropdown to any of the other options I get what I would expect…

I, [2018-10-25T20:32:36.908950 #27315]  INFO -- : ************************************
I, [2018-10-25T20:32:36.911916 #27315]  INFO -- : ARRIVED IN THE PLUGIN
I, [2018-10-25T20:32:36.915255 #27315]  INFO -- : ************************************
I, [2018-10-25T20:32:49.784835 #27315]  INFO -- : {"children_to_create"=>"Child 2"}

Finally, if I open the wizard URL, change the dropdown option from the default “All Children” and then change it back to “All Children”, hit “Done” I get…

I, [2018-10-25T20:35:26.709581 #28196]  INFO -- : ************************************
I, [2018-10-25T20:35:26.712480 #28196]  INFO -- : ARRIVED IN THE PLUGIN
I, [2018-10-25T20:35:26.715338 #28196]  INFO -- : ************************************
I, [2018-10-25T20:35:35.495961 #28196]  INFO -- : {"children_to_create"=>"All Children"}

i.e. what I would expect to see.

Bug? 2

Finally, if I set the required flag to true for the field…


…visit the URL for the wizard and, without changing the dropdown from the default “All Children” and I hit “Done” then the wizard does nothing. i.e. the “Done” button UI shows that it is being pressed but the wizard does not advance.

Now I’m guessing that Bug? 2 is a function of Bug? 1, i.e. that because the field value is only set once the dropbox value changes, then the required flag means that the field validation fails?

Let me know if you need any further information to investigate.

Feature Request

Finally, as was discussed above, would it be possible to add a Date/Datetime-aware field to the wizard?

Ideally, in the UI I’d like to see a calendar / clock picker like your event plugin and being able to specify a date range (from-to) would be wonderful. Or, at least being able to call on validation such that Date2 >= Date1.

As ever, your work is invaluable to the Discourse community.


(Danny Goodall) #219

Another feature request - sorry! but I think this would be useful to anyone developing on a development system before deploying to the live system. It’s a nice-to-have as I have found a workaround.

Import and export of wizards.

What is needed?

An export button at the Wizard level that simply returns a JSON file to the browser containing the definitions of the wizard/steps/fields.

An import button would be used to create a wizard from a previously exported JSON file.

On import, the option needs to be there to create a new wizard from the imported definition or to update an existing wizard instead.

The justification

I am creating wizards on my dev machine and using the add_step_handler feature in a series of plugins that I am developing. Your wizard is my plugin UI.

The workflow to push my plugin code from my development box and then pull the code to the live system is halted whilst I recreate the wizard on my live system - exactly as it was.

My wizards currently don’t have multiple stages and have few fields, but they feature dropdowns with many choices. The values of these choices are passed to my code and have have been reproduced exactly as they form the hash key lookup in my code. A typo would stop the code from working for that option.

As my wizards get more complex or use multi-stages, I imagine this could be a real problem.

Approach and current workaround

I see from the code that to save the wizard, you’re actually serialising it to JSON and putting that in the PluginStore so it looks like the infrastructure is there already.

I guess that you might have to implement versioning of the exported file in case a big future changes expect new keys that are not present in older files?

Knowing that you’re storing JSON allowed me to come up with a workaround. I create the wizard on the live system, dump the PluginStore table using the Data Explorer, copy the JSON and then manually insert that into my dev system’s PluginStore.

Perhaps my plugin code should create the wizards it needs by inserting rows into the custom_wizard plugin store? It would give me control but it sounds like a recipe for breaking things TBH.

I’d offer a pull request but I have no experience with the ember and the plugin UI hooks.

(Christoph) #220

I just noticed that I’m not being notified about new users joining the forum (they are asked some wizard questions after sign-up and the answers are supposed to be PMed to me).

I figured out that this was due to min trust to send messages being set to 1 (the default). So the wizard couldn’t send the message on behalf of the new (TL0) user.

I’m not sure if there is anything to be improved here, so I mainly want to mention this to anyone using the wizard to generate PMs (perhaps mention this in the OP? Or perhaps even mention it in the wizard interface when the send_pm action is selected?)

(Christoph) #221

There seems to be a bug in the plugin. I have a required field in my new user wizard but people are signing up (i.e. completing the wizard after sign-up) without filling it in.

In case it matters, here are my wizard settings:

(Angus McLeod) #222

hm ok. Thanks, I’ll take a look at that use case and account for it properly.

Can you send me a screenshot of the actual field itself? Also, can you do a test run of your wizard and see what happens?

(Christoph) #223

I thought did that before I posted but apparently I didn’t because when I try it now, I can’t reproduce it, i.e. if I leave the required field blank, I can’t go to the next step.

So all I can show you at the moment is this this list of submissions to show that several users didn’t submit field_1: even though it was required:

Not sure what you mean here.

(Angus McLeod) #224

I mean a screenshot of the relevant field settings, e.g.



  • send me a link to the wizard, so I can test it out.
  • have you changed the settings at any point?

(codechef) #225

Love this plugin, @angus! Great work.

Not sure if this is a closed issue, but running into Internet Explorer issues (still researching, but seems to be Edge on Windows 10.) Here’s relevant bits of the log.


I’m actively troubleshooting right now, but wanted to get this in front of you in case something obvious jumps out. Will post a follow up when I find a resolution.

edit: Adding top few lines of call stack for additional context.

/var/www/discourse/plugins/discourse-custom-wizard/lib/wizard.rb:26:in `initialize'
/var/www/discourse/plugins/discourse-custom-wizard/controllers/wizard.rb:45:in `new'
/var/www/discourse/plugins/discourse-custom-wizard/controllers/wizard.rb:45:in `skip'
/var/www/discourse/vendor/bundle/ruby/2.5.0/gems/actionpack-5.2.0/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'

(codechef) #226

@hellekin - I was able to resolve the same Internet Explorer issues you were running into.

@angus - Let me know if/how you’d like these changes. For now they’re forked here

Others (and future self) - This is what I found. The issue was caused by 2 main issues:

  1. IE aggressively caches page requests. GET /w/{wizard-id} from the browser returns HTML and kicks off the wizard. The ember code then makes and ajax GET to /w/{wizard-id} which returns cached HTML rather than the expected json. At that point the plugin is busted. I tweaked the ajax call to explicitly request json and bypass the cache.

  2. Once past that, I began getting client-side exceptions about entities not being a valid member of object (don’t remember the exact message.) A little googling turned up a Polyfill for IE

I made a couple minor CSS hacks to minimize IE11’s partial flex support.

Hope this helps others! Thanks again for the excellent plugin @angus