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:
Task: Add a part
We’ll start off by adding a simple component that lists child items in the tree structure.
-
Add the
child-list
component to your application:/src/main/resources/react4xp/components/parts/ChildList.tsximport {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> ); };
-
Add the
child-list
processor to your application:/src/main/resources/react4xp/components/parts/ChildListProcessor.tsimport 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), }; };
-
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; }
-
Add the
child-list
part to your component registry and data fetcher:/src/main/resources/react4xp/componentRegistry.tsimport {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.tsimport {childListProcessor} from './components/parts/ChildListProcessor'; ... export const dataFetcher = new DataFetcher(); ... dataFetcher.addPart('com.enonic.app.hmdb:child-list', {processor: childListProcessor});
-
Now you should be able to see something like this:
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
-
Add the
heading
component to your application:/src/main/resources/react4xp/components/parts/Heading.tsximport {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> };
-
Add the
heading
processor to your application:/src/main/resources/react4xp/components/parts/HeadingProcessor.tsimport 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.
-
Add the
heading
part to your component registry and data fetcher:/src/main/resources/react4xp/componentRegistry.tsimport {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.tsimport {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});
-
Now you should be able to see something like this:
In the next chapter you will make page composition even more interesting, with the introduction of layouts.