Make VC helper fields configurable

Adds KALAMAR_VC_HELPER_FIELDS environment variable and vc_helper_fields
configuration option to add or remove fields from the virtual corpus
builder at runtime.

Syntax: KALAMAR_VC_HELPER_FIELDS=+award:text,-docTitle
  +name:type  adds a field
  -name       removes a field

The result is always sorted alphabetically. Analogous to
KALAMAR_HINT_FOUNDRIES (aa6709c).

Required for DeLiKo@DNB

Change-Id: If9ad570133f78515aa6ed0ef87424c0843e76d9c
diff --git a/README.md b/README.md
index f70c4a6..68de7b7 100644
--- a/README.md
+++ b/README.md
@@ -242,6 +242,34 @@
 > **Note:** For build-time customization, `kalamar.conf.js` can still
 > be used to control which foundries are bundled into the JavaScript assets.
 
+#### VC Helper Fields
+
+![Experimental](https://img.shields.io/badge/status-experimental-orange)
+
+The virtual corpus builder fields can be configured at runtime to add or remove
+fields from the default list defined in `dev/js/src/vc/array.js`.
+
+Use `+name:type` to **add** a field and `-name` to **remove** a field.
+The result is always sorted alphabetically.
+
+```perl
+{
+  Kalamar => {
+    vc_helper_fields => ['+award:text', '-docTitle']
+  }
+}
+```
+
+```shell
+KALAMAR_VC_HELPER_FIELDS=+award:text,-docTitle perl script/kalamar daemon
+```
+
+For Docker deployments:
+
+```shell
+docker run -e KALAMAR_VC_HELPER_FIELDS=+award:text,-docTitle korap/kalamar
+```
+
 
 ### Customization
 
diff --git a/dev/js/src/init.js b/dev/js/src/init.js
index ee8f364..e98512c 100644
--- a/dev/js/src/init.js
+++ b/dev/js/src/init.js
@@ -74,6 +74,33 @@
     );
   };
 
+  // Apply configured VC helper field modifications from data-vc-helper-fields attribute
+  const vcFieldsConfig = document.body ? document.body.getAttribute('data-vc-helper-fields') : null;
+  if (vcFieldsConfig) {
+    const mods = vcFieldsConfig.split(',').map(s => s.trim()).filter(s => s.length > 0);
+    mods.forEach(mod => {
+      if (mod.startsWith('-')) {
+        // Remove field by name
+        const name = mod.substring(1);
+        const idx = vcArray.findIndex(f => f[0] === name);
+        if (idx >= 0) vcArray.splice(idx, 1);
+      } else if (mod.startsWith('+')) {
+        // Add field: +name:type
+        const spec = mod.substring(1);
+        const colonIdx = spec.indexOf(':');
+        if (colonIdx > 0) {
+          const name = spec.substring(0, colonIdx);
+          const type = spec.substring(colonIdx + 1);
+          if (!vcArray.some(f => f[0] === name)) {
+            vcArray.push([name, type]);
+          }
+        }
+      }
+    });
+    // Sort alphabetically by field name
+    vcArray.sort((a, b) => a[0].localeCompare(b[0]));
+  };
+
   KorAP.vc = vcClass.create(vcArray); 
 
   domReady(function (event) {
diff --git a/kalamar.conf b/kalamar.conf
index 4682c0a..e0ff62c 100644
--- a/kalamar.conf
+++ b/kalamar.conf
@@ -84,6 +84,13 @@
     ## Can also be set via KALAMAR_HINT_FOUNDRIES environment variable.
     ## Use '-foundry' to exclude from defaults, e.g. ['-spacy', '-corenlp']
     # hint_foundries => ['base', 'corenlp', 'dereko', 'malt',
-    #                    'marmot', 'opennlp', 'spacy', 'tt']
+    #                    'marmot', 'opennlp', 'spacy', 'tt'],
+
+    ## VC helper fields
+    ## Controls which fields are shown in the virtual corpus builder.
+    ## Can also be set via KALAMAR_VC_HELPER_FIELDS environment variable.
+    ## Use '+name:type' to add, '-name' to remove from defaults.
+    ## Result is sorted alphabetically.
+    # vc_helper_fields => ['+award:text', '-docTitle']
   }
 }
diff --git a/lib/Kalamar.pm b/lib/Kalamar.pm
index 34c7408..6832b36 100644
--- a/lib/Kalamar.pm
+++ b/lib/Kalamar.pm
@@ -375,6 +375,21 @@
   };
   $self->defaults(hint_foundries => $hint_foundries);
 
+  # Configure VC helper fields for the virtual corpus builder
+  # Can be overridden via KALAMAR_VC_HELPER_FIELDS environment variable (comma-separated)
+  # or via vc_helper_fields config option (array)
+  # Items starting with '+' add a field (format: +name:type), e.g. '+award:text'
+  # Items starting with '-' remove a field by name, e.g. '-docTitle'
+  # The result is always sorted alphabetically by field name
+  my $vc_helper_fields_spec = '';
+
+  if ($ENV{'KALAMAR_VC_HELPER_FIELDS'}) {
+    $vc_helper_fields_spec = $ENV{'KALAMAR_VC_HELPER_FIELDS'};
+  } elsif (exists $conf->{vc_helper_fields}) {
+    $vc_helper_fields_spec = join(',', @{$conf->{vc_helper_fields}});
+  };
+  $self->defaults(vc_helper_fields => $vc_helper_fields_spec);
+
   # Configure documentation navigation
   my $doc_navi = Mojo::File->new($self->home->child('templates','doc','navigation.json'))->slurp;
   $doc_navi = $doc_navi ? decode_json($doc_navi) : [];
diff --git a/t/vc_helper_fields.t b/t/vc_helper_fields.t
new file mode 100644
index 0000000..98afdaf
--- /dev/null
+++ b/t/vc_helper_fields.t
@@ -0,0 +1,41 @@
+use Mojo::Base -strict;
+use Test::More;
+use Test::Mojo;
+
+# Test vc_helper_fields default (empty)
+my $t = Test::Mojo->new('Kalamar');
+$t->get_ok('/')
+  ->status_is(200)
+  ->attr_is('body', 'data-vc-helper-fields', '');
+
+# Test KALAMAR_VC_HELPER_FIELDS environment variable
+$ENV{'KALAMAR_VC_HELPER_FIELDS'} = '+award:text,-docTitle';
+$t = Test::Mojo->new('Kalamar');
+$t->get_ok('/')
+  ->status_is(200)
+  ->attr_is('body', 'data-vc-helper-fields', '+award:text,-docTitle');
+delete $ENV{'KALAMAR_VC_HELPER_FIELDS'};
+
+# Test vc_helper_fields config option
+$t = Test::Mojo->new('Kalamar' => {
+  Kalamar => {
+    vc_helper_fields => ['+award:text', '-docTitle']
+  }
+});
+$t->get_ok('/')
+  ->status_is(200)
+  ->attr_is('body', 'data-vc-helper-fields', '+award:text,-docTitle');
+
+# Test env var takes precedence over config
+$ENV{'KALAMAR_VC_HELPER_FIELDS'} = '-author';
+$t = Test::Mojo->new('Kalamar' => {
+  Kalamar => {
+    vc_helper_fields => ['+award:text', '-docTitle']
+  }
+});
+$t->get_ok('/')
+  ->status_is(200)
+  ->attr_is('body', 'data-vc-helper-fields', '-author');
+delete $ENV{'KALAMAR_VC_HELPER_FIELDS'};
+
+done_testing;
diff --git a/templates/layouts/main.html.ep b/templates/layouts/main.html.ep
index 749dec3..b3bd049 100644
--- a/templates/layouts/main.html.ep
+++ b/templates/layouts/main.html.ep
@@ -59,6 +59,7 @@
         % $api =~ s!/$!!;
         data-korap-url="<%== $api %>"
         data-hint-foundries="<%= join(',', @{stash('hint_foundries') // []}) %>"
+        data-vc-helper-fields="<%= stash('vc_helper_fields') // '' %>"
         itemscope
         itemtype="http://schema.org/<%= stash('schematype') || 'WebApplication' %>">