From 6858e9c02e20d102f7f024a2b2760825c5e5f173 Mon Sep 17 00:00:00 2001 From: Paul Pound Date: Wed, 15 Jul 2026 11:00:30 -0300 Subject: [PATCH] added facet source to the field formatter config --- README.md | 10 ++++ .../solr_facet_field_formatter.schema.yml | 3 ++ .../SolrFacetTextFieldFormatter.php | 52 +++++++++++++++++-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 19b10ad..7942571 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,14 @@ query is resolved per field type: This matches how such fields are normally indexed and faceted in Solr — make sure the facet you select indexes the same readable value. +You can override this per field with the **Facet value** setting: + +- **Automatic** (default): referenced entity label for reference fields, the + field value otherwise. +- **Referenced entity label**: always use the referenced entity's label. +- **Raw stored value**: use the stored value — the entity id for reference + fields. Choose this when your facet indexes entity ids rather than labels. + ## Dependencies - `search_api_solr` @@ -38,6 +46,8 @@ The formatter is configured per field, under **Manage display** for the entity - **Facet:** the facet to filter on. Pick the facet configured for this field on the chosen search page. Its URL alias is used as the facet key in the generated query. +- **Facet value:** which value of the field to filter by. See + *Supported field types* above. - **Reset fulltext search** (optional): adds an empty fulltext query parameter so following the link starts a fresh, facet-only search. The parameter name (default `search_api_fulltext`) is configurable to match your view's exposed diff --git a/config/schema/solr_facet_field_formatter.schema.yml b/config/schema/solr_facet_field_formatter.schema.yml index e22323f..155258f 100644 --- a/config/schema/solr_facet_field_formatter.schema.yml +++ b/config/schema/solr_facet_field_formatter.schema.yml @@ -8,6 +8,9 @@ field.formatter.settings.solr_facet_text_field_formatter: facet_id: type: string label: 'Facet' + value_source: + type: string + label: 'Facet value source' reset_fulltext: type: boolean label: 'Reset fulltext search' diff --git a/src/Plugin/Field/FieldFormatter/SolrFacetTextFieldFormatter.php b/src/Plugin/Field/FieldFormatter/SolrFacetTextFieldFormatter.php index 8f5afe7..6c77309 100644 --- a/src/Plugin/Field/FieldFormatter/SolrFacetTextFieldFormatter.php +++ b/src/Plugin/Field/FieldFormatter/SolrFacetTextFieldFormatter.php @@ -88,6 +88,11 @@ class SolrFacetTextFieldFormatter extends FormatterBase implements ContainerFact 'facet_source' => '', // The machine name of the facet to filter on. 'facet_id' => '', + // Which value of the field to send to the facet: 'auto' (referenced + // entity label for reference fields, field value otherwise), 'label' + // (force the referenced entity label) or 'raw' (the stored value, i.e. + // the entity id for reference fields). + 'value_source' => 'auto', // Whether to reset an exposed fulltext filter on the target page so the // link produces a clean, facet-only search. 'reset_fulltext' => TRUE, @@ -122,6 +127,14 @@ class SolrFacetTextFieldFormatter extends FormatterBase implements ContainerFact '#required' => TRUE, ]; + $form['value_source'] = [ + '#type' => 'select', + '#title' => $this->t('Facet value'), + '#description' => $this->t('Which value of the field to filter the facet by. Only affects reference fields (entity reference, typed relation, …).'), + '#options' => $this->getValueSourceOptions(), + '#default_value' => $this->getSetting('value_source'), + ]; + $form['reset_fulltext'] = [ '#type' => 'checkbox', '#title' => $this->t('Reset fulltext search'), @@ -158,6 +171,13 @@ class SolrFacetTextFieldFormatter extends FormatterBase implements ContainerFact '%facet' => $this->getFacetLabel($facet_id), '%source' => $this->getFacetSourceLabel($facet_source), ]); + $value_source = $this->getSetting('value_source'); + if ($value_source && $value_source !== 'auto') { + $options = $this->getValueSourceOptions(); + if (isset($options[$value_source])) { + $summary[] = $this->t('Facet value: @value.', ['@value' => $options[$value_source]]); + } + } } else { $summary[] = $this->t('Not configured: select a facet source and facet.'); @@ -213,13 +233,31 @@ class SolrFacetTextFieldFormatter extends FormatterBase implements ContainerFact return $element; } + /** + * The available "Facet value" options for the settings form. + * + * @return array + * An array of human readable labels keyed by value source id. + */ + protected function getValueSourceOptions() { + return [ + 'auto' => $this->t('Automatic (referenced entity label, or the field value)'), + 'label' => $this->t('Referenced entity label'), + 'raw' => $this->t('Raw stored value (entity ID for reference fields)'), + ]; + } + /** * Extracts the value to filter the facet by from a field item. * - * For reference fields (entity_reference, typed_relation, …) the referenced - * entity's label is used, so the facet is filtered by the readable value - * rather than the internal entity id. For all other field types the field's - * main property value is used. + * The "Facet value" setting controls how reference fields (entity_reference, + * typed_relation, …) are resolved: + * - 'auto': the referenced entity's label, so the facet is filtered by the + * readable value rather than the internal entity id. + * - 'label': force the referenced entity's label. + * - 'raw': the stored value (the entity id for reference fields). + * + * For non-reference fields the field's main property value is always used. * * @param \Drupal\Core\Field\FieldItemInterface $item * The field item. @@ -228,11 +266,15 @@ class SolrFacetTextFieldFormatter extends FormatterBase implements ContainerFact * The facet value, or NULL if none could be determined. */ protected function getFacetValue(FieldItemInterface $item) { - if ($item instanceof EntityReferenceItem) { + $value_source = $this->getSetting('value_source'); + + if ($value_source !== 'raw' && $item instanceof EntityReferenceItem) { $entity = $item->entity; if ($entity instanceof EntityInterface) { return $entity->label(); } + // For an explicit 'label' request with no loadable entity, fall through + // to the raw value below rather than returning nothing. } $main_property = $item->getFieldDefinition()