Parts

Contents

Enonic provides a highly customizable component type called parts.

If you take a look at the person folder you might see something like this: child list no render

Task: Add a part

We’ll start off by adding a simple component that lists child items in the tree structure.

  1. Add the child-list component to your application:

    /src/main/resources/react4xp/components/parts/ChildList.tsx
    import {Part} from "@enonic/react-components";
    import React from "react";
    import styles from "./ChildList.module.css";
    
    
    export const ChildList = (props) => {
    
        const {names, paths, componentRegistry, ...extraProps} = props;
        return (
            <Part {...extraProps}>
                <ul>
                    {names.map((name, index) => (
                        <li className={styles.listItem} key={index}>
                            <a className={styles.listLink} href={paths[index]}><p>{name}</p></a>
                        </li>
                    ))}
                </ul>
            </Part>
        );
    };
  2. Add the child-list processor to your application:

    /src/main/resources/react4xp/components/parts/ChildListProcessor.ts
    import type {ComponentProcessorFunction} from '@enonic-types/lib-react4xp/DataFetcher';
    import {getChildren} from '/lib/xp/content';
    import {PartComponent} from '@enonic-types/core';
    
    export const childListProcessor: ComponentProcessorFunction<'com.enonic.app.hmdb:child-list'> = (params) => {
        const component = params.component as PartComponent;
        const sortOrder: any = component.config.sorting;
    
        const result = getChildren({
            key: params.content._id,
            start: 0,
            count: 99,
            sort: sortOrder
        });
    
        return {
            names: result.hits.map((content) => content.displayName),
            paths: result.hits.map((content) => params.request.path + '/' + content._name),
        };
    };
  3. Add the child-list CSS module to your application:

    /src/main/resources/react4xp/components/parts/ChildList.module.css
    .listItem {
      margin-block: .25rem;
    }
    
    .listLink {
      color: #61DBFB;
      text-decoration: none;
      font-weight: 500;
    }
    
    .listLink p {
      margin-block: 0;
    }
  4. Add the child-list part to your component registry and data fetcher:

    /src/main/resources/react4xp/componentRegistry.ts
    import {ChildList} from './components/parts/ChildList';
    
    ...
    
    export const componentRegistry = new ComponentRegistry();
    
    ...
    
    componentRegistry.addPart('com.enonic.app.hmdb:child-list', {View: ChildList});
    /src/main/resources/react4xp/dataFetcher.ts
    import {childListProcessor} from './components/parts/ChildListProcessor';
    
    ...
    
    export const dataFetcher = new DataFetcher();
    
    ...
    
    dataFetcher.addPart('com.enonic.app.hmdb:child-list', {processor: childListProcessor});
  5. Now you should be able to see something like this: child list render

    Try updating it by customizing the page and changing order, adding or removing items in the tree structure.

Bonus task: Heading

Since we are working with react4XP and not guillotine, we should have a head.

Add a heading to the page

  1. Add the heading component to your application:

    /src/main/resources/react4xp/components/parts/Heading.tsx
    import {Part} from '@enonic/react-components';
    import React from 'react';
    
    export const Heading = (props: any) => {
    
        const {componentRegistry, ...partProps} = props;
        return <Part {...partProps}>
            <h1>{props.heading}</h1>
        </Part>
    };
  2. Add the heading processor to your application:

    /src/main/resources/react4xp/components/parts/HeadingProcessor.ts
    import type {ComponentProcessorFunction} from '@enonic-types/lib-react4xp/DataFetcher';
    import {PartComponent} from '@enonic-types/core';
    
    export const headingProcessor: ComponentProcessorFunction<'com.enonic.app.hmdb:heading'> = (params) => {
        const component = params.component as PartComponent;
        const heading = component.config?.heading || params.content.displayName;
    
        return {
            path: '/',
            type: 'part',
            descriptor: 'com.enonic.app.hmdb:heading',
            config: params.content || {},
            heading: heading,
        };
    
    };

    Since we are using globalStyles.css to style the heading, we don’t need to add a CSS module for it.

  3. Add the heading part to your component registry and data fetcher:

    /src/main/resources/react4xp/componentRegistry.ts
    import {ChildList} from './components/parts/ChildList';
    import {Heading} from './components/parts/Heading';
    
    ...
    
    export const componentRegistry = new ComponentRegistry();
    
    ...
    
    componentRegistry.addPart('com.enonic.app.hmdb:child-list', {View: ChildList});
    componentRegistry.addPart('com.enonic.app.hmdb:heading', {View: Heading});
    /src/main/resources/react4xp/dataFetcher.ts
    import {childListProcessor} from './components/parts/ChildListProcessor';
    import {headingProcessor} from './components/parts/HeadingProcessor';
    
    ...
    
    export const dataFetcher = new DataFetcher();
    
    ...
    
    dataFetcher.addPart('com.enonic.app.hmdb:child-list', {processor: childListProcessor});
    dataFetcher.addPart('com.enonic.app.hmdb:heading', {processor: headingProcessor});
  4. Now you should be able to see something like this: header

In the next chapter you will make page composition even more interesting, with the introduction of layouts.


Contents

Contents

AI-powered search

Juke AI