INL / corpus-frontend

BlackLab Frontend, a feature-rich corpus search interface for BlackLab.
16 stars 7 forks source link

simple search mode: 'word or lemma' #532

Closed baudbaudy closed 1 month ago

baudbaudy commented 1 month ago

Hello, I am writing to you because in Blacklab's simple search mode, I would like to have a "word or lemma" search bar like on your site.

However, I have not been able to find any information on this subject or how to make this change, could you help me?

Thank you for your time and assistance.

KCMertens commented 1 month ago

We do this by indexing a copy of both word and lemma in word_or_lemma. An example BlackLab format could look like this (not an exact copy of the corpus you linked, but close enough)

# How are words annotated?
annotations:
# Make sure this is at the top of the list. The simple search is hardcoded to show the first field!
- name: word_or_lemma
  valuePath: ./text()|./@lemma # we add both of these values into this field
  displayName: Word or lemma
  multipleValues: true
  allowDuplicateValues: false

- name: word
  displayName: Word
  valuePath: ./text()
  sensitivity: sensitive_insensitive

- name: lemma
  displayName: Lemma
  valuePath: ./@lemma
  sensitivity: sensitive_insensitive

Then you'll need some config for the interface. Follow these instructions from the readme

// custom.search.js
// use word as the main display in the results table.
ui.results.shared.concordanceAnnotationId('word'); 
baudbaudy commented 1 month ago

Thank you for your answer. I followed your advice and modified my format.blf.yaml file to retrieve the 'word_or_lemma' values. However, I did not find or understand how to modify my interface file to obtain by default in 'Simple' search mode only, the 'Word or lemma' search bar. I send you the content of my custom.js file to ask you what I should modify?

`

 // Basic configuration
var config = {
    // URL to access static files (CSS, JS, etc.) for a specific index
    staticBase: CONTEXT_URL + '/' + INDEX_ID + '/static/',
    // Base color for the user interface
    baseColor: '#CC521A'
};

 // Determine if the current page is a search page
var isSearchPage = window.hasOwnProperty('vuexModules') && !!window.vuexModules.corpus;
// Determine if the current page is an article page
var isArticlePage = !!$('.container.article').length;

if (isSearchPage) {
    // Search page specific configuration
    var x = true;
    var ui = vuexModules.ui.actions;

    // Configuration of available annotations in different parts of the interface
    ui.helpers.configureAnnotations([
        // List of available features for each annotation (EXTENDED, ADVANCED, etc.)
        [                   ,    'EXTENDED'    ,    'ADVANCED'    ,    'EXPLORE'    ,    'SORT'    ,    'GROUP'    ,    'RESULTS'    ,    'CONCORDANCE'    ],
        // Words (word), lemmas (lemma), and parts of speech (pos) enabled for all features
        ['word'             ,        x         ,        x         ,        x        ,      x       ,       x       ,        x        ,          x          ],
        ['lemma'            ,        x         ,        x         ,        x        ,      x       ,       x       ,        x        ,          x          ],
        ['pos'              ,        x         ,        x         ,        x        ,      x       ,       x       ,        x        ,          x          ],
        ['word_or_lemma'    ,                 ,                  ,                 ,              ,               ,                 ,                    ],
    ]);

    // Configuration of available metadata for filtering, sorting, grouping, and exporting results
    ui.helpers.configureMetadata([
        [                     ,    'FILTER'    ,    'SORT'    ,    'GROUP'    ,    'RESULTS/HITS'    ,    'RESULTS/DOCS'    ,    'EXPORT'    ],
        // Metadata: Sender, Date, and Year enabled only for export
        ['Sender'             ,       x        ,      x       ,      x        ,                      ,                      ,        x       ],
        ['Date'               ,                ,              ,               ,                      ,                      ,        x       ],
        ['Year'               ,       x        ,      x       ,      x        ,                      ,                      ,        x       ],
        ['Writing'            ,       x        ,      x       ,      x        ,                      ,                      ,        x       ],
        ['Arrival'            ,       x        ,      x       ,      x        ,                      ,                      ,        x       ],
        ['Sent'               ,       x        ,      x       ,      x        ,                      ,                      ,        x       ],
        ['Transit'            ,       x        ,      x       ,      x        ,                      ,          x           ,        x       ],
        ['Recipient'          ,       x        ,      x       ,      x        ,                      ,                      ,        x       ],
        ['Reference'          ,       x        ,      x       ,      x        ,                      ,                      ,        x       ],
        ['Images'             ,                ,              ,               ,                      ,                      ,        x       ],
    ]);

    // vuexModules.ui.actions.results.shared.detailedAnnotationIds(['word', 'lemma', 'pos'])
    // Define a custom function to display the summary of a document in the search results
    vuexModules.ui.getState().results.shared.getDocumentSummary = function(metadata, specialFields) {
        // Extract metadata: place, date, author (or default values if unavailable)
        const place = metadata.Writing ? metadata.Writing : '[Unknown location] ';
        const date = metadata.Year ? metadata.Year : '[Date unknown]';
        const author = metadata.Sender ? metadata.Sender : '[Author unknown]';

        // Return a formatted string with the information
        return `In ${place}, ${date}, by ${author}`;
    };

    // Disable certain advanced features in extended search
    ui.search.extended.splitBatch.enable(false);
    ui.search.extended.within.enable(false);

    // Configure concordance search results
    ui.results.shared.concordanceAnnotationId('word'); // Use words for concordance
    ui.results.shared.concordanceAsHtml(true); // Display concordance results in HTML

'

KCMertens commented 1 month ago

That code looks good. I can only think of some sanity checks.

baudbaudy commented 1 month ago

Thank you very much it works! I am really sorry, I forgot this rule that the first annotation in the blf.yaml file becomes the main annotation. Thanks for your help!

KCMertens commented 1 month ago

No problem! Glad you got it working