A guide to create and render blocks and nested blocks in the React accelerator.
Are you using MVC accelerator? Then please checkout How to create blocks in MVC accelerator.
- Create a text block: how to create and render a text block which renders a text.
- Create a two columns block: how to create a block which renders text blocks in two columns layout.
Create a text block
Creating a block consists of a few steps:
- Create a block template
- Add the block to a page
- Create a component to render the block and register it in BlockContainer.tsx
- Create a GraphQL fragment to query the block's data and register it in allBlockTypes.ts
The step of creating a new block template is identical in both MVC and React accelerator. Please follow the Create a block template section to create a Text block template.
After following the previous step to create a Text block template, we should have a new block template with Text as Id and a field named Text to hold a text value. Note these Id values as we will use it in our code to query and to render the text. Now let's add a Text block to a page and enter a text "Hello world":
Now we should have a page with our Text block. Let's move on to the next step to create a TextBlock component to render the Text block. By executing yarn run generate-block-components command, it will generate components/blocks/TextBlock.tsx and also update services/blockService.ts to add the newly generated TextBlock component to a Component mapping. Now let's go ahead and modify components/blocks/TextBlock.tsx to be:
// components/blocks/TextBlock.tsx
import { Block } from 'models/block';
import { ContentFieldType } from 'models/content';
interface TextField extends ContentFieldType {
text: string;
}
interface TextBlockProps extends Block {
fields: TextField;
}
export default function TextBlock(props: TextBlockProps) {
const { text } = props.fields;
return <span>{text}</span>;
}
The component simply receives and render a Text string in a Span tag. In order to query data for the block, we should create a GraphQL fragment, which is used in allBlockTypes.ts:
// operations/fragments/blocks/text.ts
import { gql } from '@apollo/client';
export const TEXT_BLOCK_FRAGMENT = gql`
fragment TextBlock on TextBlock {
fields {
text
}
}
`;
// operations/fragments/blocks/allBlockTypes.ts
import { gql } from '@apollo/client';
import { BANNER_BLOCK_FRAGMENT } from './banner';
import { TEXT_BLOCK_FRAGMENT } from './text';
export const ALL_BLOCK_TYPES_FRAGMENT = gql`
fragment AllBlockTypes on IBlock {
... on IBlockItem {
systemId
}
...BannerBlock
...TextBlock
}
${BANNER_BLOCK_FRAGMENT}
${TEXT_BLOCK_FRAGMENT}
`;
Now let's execute yarn run dev to run the project in development mode. The browser should render a "Hello world" text.
Create a two columns layout block
Nested blocks feature was introduced in Litium 8.9, which allows editors to add block to a block. We will create a layout block which renders blocks in a two columns layout, for example, one Text block on left column and another Text block on right column. We follow same steps as creating a Text block:
Create a TwoColumns block template:
- Id: TwoColumns
- Icon: table-columns
- Include selected: Text as we will allow to add Text block as children
Edit the page we added Text block in previous step to add a TwoColumns block. Then execute yarn run generate-block-components command so it creates a TwoColumnsBlock component and register it in blockService.ts. Modify TwoColumnsBlock.tsx to contain the following code. Note we are using the same BlockContainer component, which is used in pages to render blocks, to render nested blocks.
// components/blocks/TwoColumnsBlock.tsx
import { Block } from 'models/block';
import BlockContainer from './BlockContainer';
export default function TwoColumnsBlock({ children }: { children: Block[] }) {
return (
<div className="grid grid-cols-2">
<BlockContainer blocks={children}></BlockContainer>
</div>
);
}
And the GraphQL fragment:
// operations/fragments/blocks/twoColumns.ts
import { gql } from '@apollo/client';
import { TEXT_BLOCK_FRAGMENT } from './text';
export const TWO_COLUMNS_FRAGMENT = gql`
fragment TwoColumnsBlock on TwoColumnsBlock {
children {
... on IBlockItem {
systemId
}
...TextBlock
}
}
${TEXT_BLOCK_FRAGMENT}
`;
// operations/fragments/blocks/allBlockTypes.ts
import { gql } from '@apollo/client';
import { BANNER_BLOCK_FRAGMENT } from './banner';
import { TEXT_BLOCK_FRAGMENT } from './text';
import { TWO_COLUMNS_FRAGMENT } from './twoColumns';
export const ALL_BLOCK_TYPES_FRAGMENT = gql`
fragment AllBlockTypes on IBlock {
... on IBlockItem {
systemId
}
...BannerBlock
...TextBlock
...TwoColumnsBlock
}
${BANNER_BLOCK_FRAGMENT}
${TEXT_BLOCK_FRAGMENT}
${TWO_COLUMNS_FRAGMENT}
`;
Note that in twoColumns.ts, we add only TextBlock fragment because we allow only Text block template to be added as children block. If any other block template should be added to TwoColumns block template, it should be added here. Note that we can't use AllBlockTypes fragment in TwoColumnsBlock fragment as it will form an infinitely spread.
Executing yarn run dev now and the page should render a Two columns layout block with its Text blocks inside.
Related