Rich text

Contents

In this chapter you’ll learn how to render rich text content.

Intro

Enonic boasts a rich text input type. Unlike basic text fields, rich text may contain more complex concepts such as tables, images, links and custom components. Each of these will typically need to be processed during rendering in order to provide a contextually correct URL, ideal image sizes etc.

Sample content

Luckily, the sample data set contains everyting we need to get going. The Bio field for persons is rich text, and some of the content is even populated with relevant content, like you see below:

rich text bio
Figure 1. Rich text bio field for Lea Seydoux

Rich text rendering

  1. Update the Person processor

    /src/main/resources/react4xp/components/content/PersonProcessor.ts
    import {processHtml} from '/lib/enonic/react4xp';
    
    ...
    
    
    export const personProcessor: ComponentProcessorFunction<PageDescriptor>
        = (params) => {
    ...
    
        return {
            displayName: `${params.content.displayName}`,
            photo: {
                _id,
                title: displayName,
                imageUrl: imageUrl({id: _id, scale: 'block(1200, 675)'})
            },
            birthDate: params.content.data.dateofbirth,
            restPhotos: extraPhotos,
            parent: parentPath(params.request.path),
            bio: `${params.content.data.bio}`,
            bioHtml: processHtml({
                value: params.content.data.bio as string,
                imageWidths: [200, 400, 800],
            })
        };
    };

    ProcessHtml is a function to prepare data for the RichText component that already comes with react4xp.

  2. add it to your component

    /src/main/resources/react4xp/components/content/Person.tsx
    import {componentRegistry} from '/react4xp/componentRegistry';
    import {RichText} from '@enonic/react-components';
    
    ...
    
    export const Person = (props) => {
        const {parent, displayName, photo, restPhotos, bioHtml, birthDate} = props as any;
    
    ...
    
        {
            bioHtml && (
                <>
                    <h2>Bio</h2>
                    <div className={styles.richText}>
                        <RichText
                            data={bioHtml}
                            componentRegistry={componentRegistry}
                            loading="lazy"
                        />
                    </div>
                </>
            )
        }
    </div>
    )
    }
  3. Et voilà!

    And just like that we have a fully functional rich text renderer.

    The page should look something like this:

    rich text result
    Figure 2. Person content rendered with rich text

If you have a sharp eye, you might notice there is something missing, we need to add a macro component to render factbox!

Macro component

Adding the Fact-Box is easy, we just need to add a new component that will be used to render the macro:

  1. Component

    /src/main/resources/react4xp/components/macro/FactBox.tsx
    import {MacroComponentParams} from '@enonic/react-components';
    import React from 'react';
    import styles from './FactBox.module.css';
    
    
    export const Factbox = ({config, children}: MacroComponentParams) => {
        // Creating an object for dangerouslySetInnerHTML
        return (
            <ins className={styles.factbox}>
                <i className={styles.icon}/>
                <strong className={styles.header}>{config.header ? config.header as string : "Fact Box"}</strong>
                <div className={styles.bodyContent}> {children}</div>
            </ins>
        );
    };
  2. Styling

    /src/main/resources/react4xp/components/macro/FactBox.module.css
    @font-face {
      font-family: 'icomoon';
      src: url('../../public/fonts/icomoon.woff') format('woff');
    }
    
    .icon {
      font-family: 'icomoon', 'sans-serif' !important;
      font-style: normal;
      -webkit-font-smoothing: antialiased;
    }
    
    .factbox {
      background-color: ghostwhite;
      color: #151d4e;
      display: block;
      text-decoration: none;
      border-radius: 5px;
      clear: both;
      box-shadow: 0 2px 3px #b6b6b6;
      padding: 10px 20px;
      max-width: fit-content;
      margin: 1rem;
      position: relative;
    }
    
    .factbox .header {
      font-size: 20px;
      line-height: 24px;
      margin: 0 0 0 1rem;
    }
    
    .factbox .icon:before {
      content: "\e0c9";
      color: #4b93bd;
    }
  3. Register the component

    /src/main/resources/react4xp/componentRegistry.tsx
    import {ComponentRegistry} from '@enonic/react-components';
    import {Person} from './components/content/Person';
    import {Hello} from './components/hello/Hello';
    import {Factbox} from './components/macro/FactBox';
    
    export const componentRegistry = new ComponentRegistry();
    
    componentRegistry.addContentType('portal:site', {View: Hello});
    componentRegistry.addContentType('com.enonic.app.hmdb:person', {View: Person});
    componentRegistry.addMacro('factbox', {View: Factbox});
  4. Factbox complete!

    You should now see Lea Seydoux updated with the FactBox macro:

    rich text with macro
    Figure 3. Person content rendered with rich text and macro

Sweet! next up pages.


Contents

Contents

AI-powered search

Juke AI