Source code - Fluid Topics - Latest

Fluid Topics Designer Guide

Category
Reference Guides
Audience
public
Version
Latest

The following example relies on:

  • The Map variable (contains information about the current open map).
  • The Topic variable (contains information about the current open topic).

To use this example in a Result template, use the result variable.

To add the same Custom component:

  1. In the HTML panel, copy and paste the following:

    <div class="center-controls">
      <ft-select id="language-select" label="Select a language" icon="translate">
        <!-- The JavaScript code generates the <option> elements with the content of the 'languages' array -->
      </ft-select>
      <ft-button id="translation-launch-button" icon="TRANSLATE_SPARKLE_SOLID">Translate</ft-button>
      <div id="loader">Translating...</div>
      <div id="error"></div>
    </div>
    
    <h1 id="title"></h1>
    <div id="translated_content"></div>
    
  2. In the CSS panel, copy and paste the following:

    #translated_content, #title {
      margin-inline: 25%;
    }
    
    #loader {
      display: none; /* Appears dynamically */
    }
    
    #error {
      color: red;
    }
    
    .center-controls {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 10px;
    }
    
    .center-controls ft-select {
      min-width: 250px;
      max-width: 100%;
    }
    
  3. In the JS panel, copy and paste the following:

    const languages = [
      { label: "French", value: "fr" },
      { label: "Spanish", value: "es" },
      { label: "German", value: "de" },
      { label: "Italian", value: "it" }
    ];
    
    const select = document.getElementById('language-select');
    
    for (const lang of languages) {
      const option = document.createElement('ft-select-option');
      option.setAttribute('label', lang.label);
      option.setAttribute('value', lang.value);
      select.appendChild(option);
    }
    
    const button = document.querySelector('#translation-launch-button');
    const contentElement = document.querySelector('#translated_content');
    const loaderElement = document.querySelector('#loader');
    const errorElement = document.querySelector('#error');
    const title = document.querySelector('#title');
    
    let selectedLang = null;
    let currentLang = null;
    
    select.addEventListener('change', (e) => {
      selectedLang = e.detail;
      errorElement.textContent = '';
    
      // Activate only if not the same as already-displayed lang
      button.disabled = (selectedLang === currentLang);
    });
    
    button.addEventListener('click', async () => {
      loaderElement.style.display = '';
      errorElement.textContent = '';
    
      try {
        const response = await FluidTopicsTranslationService.translate({
          profileId: 'traduzco',
          destinationLanguage: selectedLang,
          format: 'html',
          topic: {
            mapId: map.id,
            tocId: topic.contentId
          },
          titleElement: title,
          contentElement: contentElement,       
          loaderElement: loaderElement,
          errorElement: errorElement
        });
        contentElement.innerHTML = response.content;
        loaderElement.style.display = 'none';
        button.disabled = true;
        currentLang = selectedLang; // Remember which language is rendered
      } catch (err) {
        loaderElement.style.display = 'none';
        errorElement.textContent = err.message;
      }
    });
    
    // Deactivated on page load, activates when the user selects a language
    button.disabled = true;
    
  4. Replace the profileId value by a valid translation profile ID.

  5. Save the component.

  6. Save and publish the page.