From 4d7274b938bc6d1af7ae4486a6d3e00d89e2d5d3 Mon Sep 17 00:00:00 2001 From: Chuck Date: Sun, 4 Jan 2026 20:08:16 -0500 Subject: [PATCH] Add array-of-objects widget support to server-side template Add detection and rendering for array-of-objects in the Jinja2 template (plugin_config.html). This enables the custom_feeds widget to display properly with name, URL, enabled checkbox, and logo upload fields. The widget is detected by checking if prop.items.type == 'object' && prop.items.properties, and is rendered before the file-upload widget check. --- .../templates/v3/partials/plugin_config.html | 111 +++++++++++++++++- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/web_interface/templates/v3/partials/plugin_config.html b/web_interface/templates/v3/partials/plugin_config.html index 52fa4727..8264645d 100644 --- a/web_interface/templates/v3/partials/plugin_config.html +++ b/web_interface/templates/v3/partials/plugin_config.html @@ -58,10 +58,115 @@ {% if field_type == 'integer' %}step="1"{% else %}step="any"{% endif %} class="form-input w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 bg-white text-black placeholder:text-gray-500"> - {# Array - check if it's a file upload widget #} + {# Array - check if it's an array of objects first, then file upload widget #} {% elif field_type == 'array' %} - {% set x_widget = prop.get('x-widget') or prop.get('x_widget') %} - {% if x_widget == 'file-upload' %} + {% set items_schema = prop.get('items') or {} %} + {% set is_array_of_objects = items_schema.get('type') == 'object' and items_schema.get('properties') %} + {% if is_array_of_objects %} + {# Array of objects widget (like custom_feeds with name, url, enabled, logo) #} + {% set item_properties = items_schema.get('properties', {}) %} + {% set max_items = prop.get('maxItems', 50) %} + {% set array_value = value if value is not none and value is iterable and value is not string else (prop.default if prop.default is defined and prop.default is iterable and prop.default is not string else []) %} + +
+
+ {% for item in array_value %} + {% set item_index = loop.index0 %} +
+ {% for prop_key, prop_schema in item_properties.items() %} + {% set prop_value = item.get(prop_key, prop_schema.get('default')) %} + {% set prop_label = prop_schema.get('title') or prop_key|replace('_', ' ')|title %} + {% set prop_description = prop_schema.get('description') or '' %} + {% set prop_full_key = full_key ~ '[' ~ item_index ~ '].' ~ prop_key %} + {% set prop_field_id = field_id ~ '_item_' ~ item_index ~ '_' ~ prop_key %} + +
+ {% if prop_schema.get('x-widget') == 'file-upload' %} + {# File upload widget for logo field #} + {% set upload_config = prop_schema.get('x-upload-config') or {} %} + {% set plugin_id_from_config = upload_config.get('plugin_id', plugin_id) %} + {% set allowed_types = upload_config.get('allowed_types', ['image/png', 'image/jpeg', 'image/bmp']) %} + + + {% if prop_description %} +

{{ prop_description }}

+ {% endif %} + +
+ + + + {% if prop_value and prop_value.get('path') %} +
+ Logo + +
+ {% endif %} +
+ {% elif prop_schema.get('type') == 'boolean' %} + {# Boolean checkbox #} + + {% else %} + {# Regular text/string input #} + + {% if prop_description %} +

{{ prop_description }}

+ {% endif %} + + {% endif %} +
+ {% endfor %} + +
+ +
+
+ {% endfor %} +
+ + + + +
+ {% elif prop.get('x-widget') == 'file-upload' or prop.get('x_widget') == 'file-upload' %} {# File upload widget for arrays #} {% set upload_config = prop.get('x-upload-config') or {} %} {% set max_files = upload_config.get('max_files', 10) %}