User-friendly presentation of custom registration field data

Hey everyone,

I am setting up Indico for a conference with rather complicated hotel booking and pricing requirements. Upon registration users have to select hotel categories and the price for accompanying persons also depends on that hotel category.

My solution is to write a plugin that encapsulates all options and the resulting price as a custom registration field - and while searching for all required APIs and setting up the (to me) unfamiliar toolchains and frameworks took me ages, I am deeply impressed by the plugin system as it allowed me to do pretty much all I needed. And all as a plugin in a way that feels future proof in the sense that I do not worry that updating Indico will break my plugin.

There is only one issue that I cannot seem to fix in an elegant way:

In the registration overview as well as in the receipt emails the complex data from my field is presented as a JSON object. I need to rewrite it in a user-friendly way. So, I looked into how the built-in accommodation field in Indico does it to find that its formatting is pretty much a hardcoded special case in the respective templates.

So, tldr:

  • Is there a way to get custom formatting for my field into these templates without overwriting them entirely? (I am sure that overwriting them will require me to patch all those templates each time I update Indico)
  • Using the for_humans parameter of get_friendly_data to produce a well-formatted string would be fine, too, but for_humans is not used for these parts. Would it make sense to suggest using it as a default for those templates in the next release of Indico? To me this seems to be the intended use of this parameter and most fields do not have special requirements here…
  • As a last resort: Are there any drawbacks to returning a human-readable string instead of JSON for all calls to get_friendly_data regardless of for_humans? Is this used somewhere except for field-specific templates that do not apply to my field anyway?
1 Like

Try adding this patch to the core and then implement those template hooks:

diff --git a/indico/modules/events/registration/templates/display/_registration_summary_blocks.html b/indico/modules/events/registration/templates/display/_registration_summary_blocks.html
index 4c547fdca1..c2637eaf7f 100644
--- a/indico/modules/events/registration/templates/display/_registration_summary_blocks.html
+++ b/indico/modules/events/registration/templates/display/_registration_summary_blocks.html
@@ -107,7 +107,8 @@
                              url_for('.registration_picture', data[field.id].locator.registrant_file) %}
         <img class="picture-preview" src="{{ picture_url }}" alt="{{ friendly_data }}">
     {% elif friendly_data is not none %}
-        {{- friendly_data -}}
+        {{- template_hook('registration-summary-blocks-render-data', type=field.input_type, friendly_data=friendly_data)
+            or friendly_data -}}
     {% endif %}
 {% endmacro %}

diff --git a/indico/modules/events/registration/templates/emails/base_registration_details.html b/indico/modules/events/registration/templates/emails/base_registration_details.html
index cdcedb169f..27528b7b15 100644
--- a/indico/modules/events/registration/templates/emails/base_registration_details.html
+++ b/indico/modules/events/registration/templates/emails/base_registration_details.html
@@ -99,7 +99,8 @@
     {%- elif type == 'picture' and friendly_data -%}
         {{- render_picture(friendly_data, raw_data) -}}
     {%- else -%}
-        {{- friendly_data -}}
+        {{- template_hook('registration-email-render-data', type=type, friendly_data=friendly_data, raw_data=raw_data)
+            or friendly_data -}}
     {%- endif -%}
 {% endmacro %}

diff --git a/indico/modules/events/registration/templates/management/_reglist.html b/indico/modules/events/registration/templates/management/_reglist.html
index 9736790daf..df104f5a21 100644
--- a/indico/modules/events/registration/templates/management/_reglist.html
+++ b/indico/modules/events/registration/templates/management/_reglist.html
@@ -162,11 +162,20 @@
                                             {%- endif %}
                                         </td>
                                     {% else %}
-                                        <td class="i-table" data-text="{{ search_value }}">
-                                            {%- if item.id in data and data[item.id].friendly_data %}
-                                                {{- data[item.id].friendly_data }}
-                                            {%- endif %}
-                                        </td>
+                                        {% set custom_column = (
+                                            template_hook('registration-list-render-data', type=data[item.id].field_data.field.input_type, friendly_data=data[item.id].friendly_data)
+                                            if item.id in data
+                                            else none
+                                        ) %}
+                                        {% if custom_column %}
+                                            {{ custom_column }}
+                                        {% else %}
+                                            <td class="i-table" data-text="{{ search_value }}">
+                                                {%- if item.id in data and data[item.id].friendly_data %}
+                                                    {{- data[item.id].friendly_data }}
+                                                {%- endif %}
+                                            </td>
+                                        {% endif %}
                                     {% endif %}
                                 {% endfor %}
                             </tr>

Happy to add them upstream if they do the job. They are untested, so maybe there’s a type somewhere.

Would it make sense to suggest using it as a default for those templates in the next release of Indico? To me this seems to be the intended use of this parameter and most fields do not have special requirements here…

This code is a bit messy so I’d rather not touch it w/o cleaning it up a bit altogether.

1 Like

Perfect, thanks a lot! Exactly what I needed and works like a charm.

May I ask for one additional hook in _registration_summary_blocks.html to also format friendly_data in the invoice section?

diff --git a/indico/modules/events/registration/templates/display/_registration_summary_blocks.html b/indico/modules/events/registration/templates/display/_registration_summary_blocks.html
index 22c50cef93..d52ac74a43 100644
--- a/indico/modules/events/registration/templates/display/_registration_summary_blocks.html
+++ b/indico/modules/events/registration/templates/display/_registration_summary_blocks.html
@@ -106,7 +106,8 @@
                              url_for('.registration_picture', data[field.id].locator.registrant_file) %}
         <img class="picture-preview" src="{{ picture_url }}" alt="{{ friendly_data }}">
     {% elif friendly_data is not none %}
-        {{- friendly_data -}}
+        {{- template_hook('registration-summary-blocks-render-data', type=field.input_type, friendly_data=friendly_data)
+            or friendly_data -}}
     {% endif %}
 {% endmacro %}
 
@@ -277,7 +278,8 @@
                                 {% elif item.field_data.field.input_type == 'multi_choice' %}
                                     {{ item.friendly_data | join(', ') }}
                                 {% else %}
-                                   {{ item.friendly_data }}
+                                    {{- template_hook('registration-summary-invoice-render-data', type=item.field_data.field.input_type, friendly_data=item.friendly_data)
+                                        or item.friendly_data -}}
                                 {% endif %}
                             </td>
                             <td class="text-right">{{ item.render_price() }}</td>

(This diff is against the v3.3.6 release, though, and I am not sure if the name for the hook is to your taste.)

So, can I plan for those hooks to be included in the next release?

Would you mind sending a PR containing both mine and your changes? Easier to take care of it that way, also because I’m currently on something else. But yes, I don’t see why this would not make it into the next release.

Wanted to say ā€œdoneā€, but you already fixed a typo in my PR’s title while I was still waiting for the automated tests to finish :slight_smile:

Thanks, again!