# Embedding entities - teasers and full size

**URL:** <https://community.fibery.io/t/embedding-entities-teasers-and-full-size/5990>\
**Category:** Fibery Showcase\
**Created:** [March 18, 2024, 4:49am UTC](https://community.fibery.io/t/embedding-entities-teasers-and-full-size/5990 "2024-03-18T04:49:17Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yuri\_BC](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/yuri_bc/32/8803_2.png) [@Yuri\_BC](https://community.fibery.io/u/Yuri_BC)\
**Post date:** [March 18, 2024, 4:49am UTC](https://community.fibery.io/t/embedding-entities-teasers-and-full-size/5990/1 "2024-03-18T04:49:17Z")

</div>

Here is a working script that turns Mention links into embedded teaser displays or embedded ful size entity displays. Note: these are snapshots, not live mirrored embeds. But they can be included and updated with buttons.

![chrome_jGYvThrVCM](https://us1.discourse-cdn.com/flex020/uploads/fibery/original/2X/9/9161a0f58d7ee666cdb532e229dcda362b4867eb.gif)

## Explanation

1. **nitialization** : Sets up the Fibery service, defines constants for the type of page (`yoPageType`), a mapping of database IDs to their corresponding types, character limits for text truncation, and a base URL for constructing “Read more” links.
2. **Main Function - `enrichDescriptionWithEntityDataV2_2`** :

- Retrieves the current entity’s description.
- If a description exists, it fetches the document content and processes it for specific patterns (`[[#^databaseId/entityId]]`).
- Updates the document content with the enriched description.

1. **Pattern Processing - `processTextPatternsV2_2`** :

- Searches the document content for patterns that represent links to other entities within the same Fibery workspace.
- For each pattern found, it fetches the corresponding entity’s description and public ID.
- Adjusts header levels within the teaser text from `#`, `##`, or `###` to `####` to maintain consistency and avoid hierarchy conflicts.
- Truncates the fetched description to a specified character limit if necessary and removes any leading empty lines.
- Constructs a “Read more” link if the description is truncated.
- Embeds the modified content into the original document, replacing the pattern with a blockquote containing the teaser (the entity’s adjusted description and optionally the “Read more” link).

1. **Description Truncation - `truncateDescriptionV2_2`** :

- Truncates the entity description to a predefined character limit, ensuring the text ends on a full word and appending an ellipsis to indicate truncation.

1. **Execution** :

- The script executes the main function `enrichDescriptionWithEntityDataV2_2` to start the process of enriching document descriptions based on the specified patterns.

## Script - Only the teasers button

(Replace SpaceName/DatabaseName with your ones, as well as the const databaseIdMap Database UUID)

```auto
const fibery = context.getService('fibery');
const yoPageType = 'SpaceName/DatabaseName'; 
const databaseIdMap = { '8ff09230-0883-11ee-a2e3-dd72e97a05a2': 'SpaceName/DatabaseName' };
const characterLimit = 400;
const baseUrl = 'https://cce.fibery.io/SpaceName/DatabaseName/';

async function enrichDescriptionWithEntityDataV2_2() {
    try {
        const currentEntity = args.currentEntities[0];
        const yoPageEntity = await fibery.getEntityById(yoPageType, currentEntity.id, ['Description']);
        if (yoPageEntity.Description && yoPageEntity.Description.Secret) {
            let descriptionContent = await fibery.getDocumentContent(yoPageEntity.Description.Secret, 'md');
            descriptionContent = await processTextPatternsV2_2(descriptionContent);
            await fibery.setDocumentContent(yoPageEntity.Description.Secret, descriptionContent, 'md');
        }
    } catch (error) {
        console.error('Error in script:', error);
    }
}

async function processTextPatternsV2_2(descriptionContent) {
    const regex = /(?:^|\n)\[\[#\^(.*?)\/(.*?)\]\](?=\n|$)/g;
    let match;
    let modifiedContent = descriptionContent;
    let offsetAdjustment = 0;

    while ((match = regex.exec(descriptionContent)) !== null) {
        const fullMatch = match[0].trim(); // Trim to remove any leading newline from the match
        const databaseId = match[1].trim(), entityId = match[2].trim();

        // Calculate the actual index of the match considering previous adjustments
        const actualMatchIndex = match.index + offsetAdjustment + (match[0].startsWith('\n') ? 1 : 0); // Adjust index if match started with a newline

        if (!databaseIdMap[databaseId]) {
            console.error(`Database ID mapping not found for ${databaseId}.`);
            continue;
        }

        try {
            const fiberyTypeName = databaseIdMap[databaseId];
            const entity = await fibery.getEntityById(fiberyTypeName, entityId, ['Description', 'Public Id']);
            if (entity.Description && entity.Description.Secret) {
                let entityDescriptionContent = await fibery.getDocumentContent(entity.Description.Secret, 'md');

                // Convert headers #, ##, ### to #### in the teaser text
                entityDescriptionContent = entityDescriptionContent.replace(/^(>?\s*)(#{1,3})\s/gm, '$1#### ');

                const { text: truncatedText, isTruncated } = truncateDescriptionV2_2(entityDescriptionContent, characterLimit);
                entityDescriptionContent = truncatedText.replace(/^\s*[\r\n]/gm, ''); // Remove empty lines
                const readMoreLink = isTruncated && entity['Public Id'] ? ` [Read more](${baseUrl}${entity['Public Id']})` : '';
                const headerText = `## ${fullMatch}`;
                const contentToBeQuoted = `${headerText}\n${entityDescriptionContent}${readMoreLink}\n`.trim();
                const quotedBlock = contentToBeQuoted.split('\n').map(line => `> ${line}`).join('\n');

                modifiedContent = modifiedContent.slice(0, actualMatchIndex) + quotedBlock + modifiedContent.slice(actualMatchIndex + fullMatch.length);
                offsetAdjustment += quotedBlock.length - fullMatch.length;
            }
        } catch (error) {
            console.error(`Error fetching entity or entity Description for ID ${entityId}:`, error);
        }
    }
    return modifiedContent;
}

function truncateDescriptionV2_2(description, maxLength) {
    if (description.length <= maxLength) return { text: description, isTruncated: false };
    const truncated = description.substr(0, description.lastIndexOf(' ', maxLength)) + ' ...';
    return { text: truncated, isTruncated: true };
}

await enrichDescriptionWithEntityDataV2_2();

```

---

<div class="post-metadata">

**Author:** ![mvnrsa](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/mvnrsa/32/8858_2.png) [@mvnrsa](https://community.fibery.io/u/mvnrsa)\
**Post date:** [March 18, 2024, 3:52pm UTC](https://community.fibery.io/t/embedding-entities-teasers-and-full-size/5990/2 "2024-03-18T15:52:22Z")

</div>

Hi,

Tx for sharing this.

---

<div class="post-metadata">

**Author:** ![Oshyan](https://sea2.discourse-cdn.com/flex020/user_avatar/community.fibery.io/oshyan/32/11431_2.png) [@Oshyan](https://community.fibery.io/u/Oshyan)\
**Post date:** [March 18, 2024, 6:19pm UTC](https://community.fibery.io/t/embedding-entities-teasers-and-full-size/5990/3 "2024-03-18T18:19:13Z")

</div>

Wow, this is pretty cool! I have definitely wanted the option to embed individual entities in another entity or page, either as a full embed, or as a “card” or something more expansive/visual than the existing (but great) Reference capability. I’m not sure I’ll use this workaround, but I like that it points the way to this kind of functionality, which will hopefully become native one day. I envision something similar to how URL embeds are treated currently, with the option to have the current in-line behavior, a “Card” view, perhaps an “Excerpt” view as you have created here, and the “full” embed as well.
