Go to main content Go to main menu

Configuring FAQ Manager

The FAQ Manager helps generate Frequently Asked Questions (FAQs) from existing text content. It analyzes the source text and produces a structured list of question - answer pairs that can be rendered in different page or block contexts.

FAQ Data Models

The FAQ data model consists of two core concepts: FAQ Item and FAQ List. Together, they define how FAQ content is structured, generated, and managed.

FAQ Item

A FAQ Item represents a single question - answer pair generated from source text or created manually. It is the smallest unit of FAQ content and is typically rendered as one expandable or inline entry in the UI.

A FAQ Item can be implemented either as:

  • An Optimizely block, or
  • A plain model

Example: FAQ Item as a block

using Epinova.CMS.AiAssistant.Faqs;
using System.ComponentModel.DataAnnotations;

[ContentType(GUID = "411E6051-319F-46B6-A8E6-5DAF38419819")]
public class FaqBlock : BlockData, IFaq
{
    [CultureSpecific]
    public virtual string Question { get; set; }

    [CultureSpecific]
    public virtual string Answer { get; set; }

    [ScaffoldColumn(false)]
    [CultureSpecific]   // Important for use with the LanguageManager add-on
    public virtual Guid Id { get; set; } = Guid.NewGuid();

    public override void SetDefaultValues(ContentType contentType)
    {
        base.SetDefaultValues(contentType);

        // Only set a new GUID if the current one is empty
        if (Id == Guid.Empty)
        {
            Id = Guid.NewGuid();
        }
    }
}

IFaq Marker Interface

IFaq is a marker interface used to identify a model as FAQ Item.

IFaq interface

public interface IFaq
{
    public Guid Id { get; set; }
}

Built-in FAQ Item Models

The following plain models are provided out of the box:

  • Epinova.CMS.AiAssistant.Faqs.Faq
  • Epinova.CMS.AiAssistant.Faqs.XhtmlStringFaq

Faq plain model

public class Faq : IFaq
{
    [Editable(false)]
    public virtual Guid Id { get; set; } = Guid.NewGuid();

    public virtual string Question { get; set; } = string.Empty;

    public virtual string Answer { get; set; } = string.Empty;
}

 

XhtmlStringFaq plain model

public class XhtmlStringFaq : IFaq
{
    [Editable(false)]
    public virtual Guid Id { get; set; } = Guid.NewGuid();

    public virtual string? Question { get; set; }

    public virtual XhtmlString? Answer { get; set; }
}

FAQ List

A FAQ List is a collection of FAQ Items managed as a single unit. There're multiple ways to define FAQ list, depends on how FAQ items are represented.

Example: Using the FAQ item in different scenarios

public virtual IList<FaqBlock> FaqBlockList { get; set; }

public virtual IList<Faq> FaqList { get; set; }

public virtual IList<XhtmlStringFaq> XhtmlStringFaqList { get; set; }

Note: You can mark these properties with [CultureSpecific] attribute to enable multilingual support.

Supported Usage Scenarios

1. FAQ Block (Shared Block) Scenario

Use this scenario when FAQs are added via a shared FAQ block placed in a content area.

Source text

The main text content located at the same level as the content area in which the FAQ block is placed.

Behavior

FAQs are generated only from text fields available on the content.

Limitation

Because a shared block can be reused across multiple pages or content items, the source text may differ between usages, therefore the generated FAQs may be based on content that does not match the current page context.

Example: FAQ List block

[ContentType(GUID = "DBC1C6F9-B2A8-4F01-85E7-6E69DE03FA6F")] 
public class FaqListBlock : BlockData
{
    [AiFaqsGenerator]
    public virtual IList<FaqBlock> FaqList { get; set; }
}

The AiFaqsGenerator attribute is applied to the property to specify the content source used for generating FAQs.

By default, the attribute does not require a source property to be specified. If no source property name is provided, the FAQ generator uses the page's content as the source text for generating FAQs.

You may optionally specify a source property name to control which content field is used for generation. The source property must exist on the same content type as the property decorated with AiFaqsGenerator.

Note: A shared block must be referenced by at least one page before it can be included in the scan.

2. FAQ Page Scenario

Use this scenario when a page contains a main text content and a list of FAQs rendered on the same page.

Source text

The main text content of the page.

FAQs content

The page property that stores the FAQ item list.

Behavior

FAQs are generated from the page's content and displayed alongside the main content.

There're multiple ways to configure FAQ List on a page, depending on requirements.

  • A list of FAQ item blocks
  • A property list of plain FAQ models.

Example: FAQ page with a list of FAQ blocks

[ContentType(GUID = "77D2E45C-ED9B-40E7-B672-E693616D3472")]
public class FaqPage : PageData
{
    public virtual XhtmlString MainBody { get; set; }

    public virtual ContentArea MainContentArea { get; set; }

    [AiFaqsGenerator]
    public virtual IList<FaqBlock> FaqBlockList { get; set; }
}

Example: FAQ page with a list of XhtmlStringFaq model

[ContentType(GUID = "77D2E45C-ED9B-40E7-B672-E693616D3472")]
public class FaqPage : PageData
{
    public virtual XhtmlString MainBody { get; set; }

    public virtual ContentArea MainContentArea { get; set; }

    [AiFaqsGenerator]
    [EditorDescriptor(EditorDescriptorType = typeof(XhtmlStringFaqListEditorDescriptor))]
    public virtual IList<XhtmlStringFaq> XhtmlStringFaqList { get; set; }
}

FAQ Model Converter

AI Assistant uses its own internal model to store and manage FAQ content. Because FAQ Item model can vary between applications, a model converter is requried to map site-specific FAQ Item model to the AI Assistant model.

Built-in model converters are provided for:

  • Faq
  • XhtmlStringFaq

If FaqBlock is used as a FAQ Item, a custom model converter must be implemented.

Example: FAQ block model converter

public class FaqBlockModelConverter : FaqModelConverterBase<FaqBlock>
{
    public override bool IsXhtmlStringQuestion => false;

    public override bool IsXhtmlStringAnswer => false;

    public override FaqBlock ConvertFromModel(IContentRepository contentRepository, ContentReference? parentContentLink, FaqModel model)
    {
        var block = contentRepository.GetDefault<FaqBlock>(parentContentLink);
        block.Id = model.Id;
        block.Question = model.Question;
        block.Answer = model.Answer;
        return block;
    }

    public override FaqModel ConvertToModel(FaqBlock faq) =>
        new()
        {
            Id = faq.Id == Guid.Empty ? Guid.NewGuid() : faq.Id,
            Question = faq.Question ?? string.Empty,
            Answer = faq.Answer ?? string.Empty
        };
}

Registering Model Converters

using Epinova.CMS.AiAssistant.Faqs;

public void ConfigureServices(IServiceCollection services)
{
   ....
   services
      .AddAiAssistant()
      .AddFaqModelConverter<FaqModelConverter>() // When Faq is used
      .AddFaqModelConverter<XhtmlStringFaqModelConverter>() // When XhtmlStringFaq is used
      .AddFaqModelConverter<FaqBlockModelConverter>(); // When FaqBlock is used
}              

FAQ Configuration Summary

To configure FAQ generation in your site, follow these steps:

1. Define FAQ Item Models

Choose how a FAQ Item is represented in your solution:

  • Use a built-in plain model Faq or XhtmlStringFaq
  • Create a custom model or Optimizely block that implements IFaq

Ensure each FAQ Item has a unique Id.

2. Define a FAQ List

Create a property that represents a FAQ List by using one of the following:

  • A list of FAQ Item blocks
  • A list of plain FAQ models
  • A local FAQ List block

This property will act as the container for generated FAQs.

3. Bind Source Text Using AiFaqsGenerator

Decorate the FAQ List property with the AiFaqsGenerator attribute to specify the source text used for FAQ generation.

4. Choose the Usage Scenario

Select the appropriate usage pattern based on content requirements:

  • FAQ Page - for page-specific, tightly coupled FAQs
  • FAQ Block (Shared block) - for reusable or generic FAQs

Be aware of the limitations of shared blocks when content context differs.

5. Implement a FAQ Model Converter (If Required)

If a custom FAQ Item type is used (for example, FaqBlock), implement a FAQ model converter to map between site models and the AI Assistant internal model.

Built-in converters are available for Faq and XhtmlStringFaq.

6. Register FAQ Model Converters

Register all required model converters during application startup.