130
0

[ WordPress ] Tìm hiểu InnerBlock và Select Control trong Gutenberg

130
gutenberg-1
Thời gian đọc: 5 phút

Chào các bạn, với bài lần trước team mình đã hướng dẫn các bạn các sử dụng 2 components Gutenberg của WordPress là MediaPlaceholder và RichText các bạn có thể coi lại tại đây. Thì với bài viết lần này mình sẽ tiếp tục hướng dẫn các sử dụng một số component khác thông qua viết tạo block hiển thị card profile grid layout cho post (page, custom post type,…).

Tìm hiểu về Inner Block và Select Control

InnerBlock

Đây là component của WordPress giúp chúng ta có thể tạo 1 vùng để user có thể thêm các block tuỳ ý hoặc thêm, thao tác các block mà chúng ta cố định sẵn. Để hiểu sơ việc sử dụng block này mời các bạn xem đoạn code bên dưới:

const {registerBlockType} = wp.blocks
const {useBlockProps, InnerBlocks} = wp.blockEditor
//import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
//import { registerBlockType } from '@wordpress/blocks'

registerBlockType('wolfactive-demo-innerblock', { 
   title: "Demo InnerBlock", 
   description: "Block này để demo InnerBlock", 
   category: "wolfactive", 
   attributes: {},
   icon: "wordpress", 
   keywords:["wolfactive","wordpress"], 
   edit: ({attributes, setAttributes}) => {
       const blockProps = useBlockProps();
       return <div { ...blockProps }> <InnerBlocks /></div>
   }, 
   save: ({attributes}) => {
       const blockProps = useBlockProps.save();

		return (
			<div { ...blockProps }>
				<InnerBlocks.Content />
			</div>
		);
   } 
})

Sau khi các bạn register xong block trên vào editor kéo block mới tạo ra sẽ thấy dấu cộng xuất hiện trong block mới tạo. Khi các bạn nhấn vào các bạn có thể chọn được block mà bạn muốn thêm vào như hình bên dưới.

wordpress-gutenberg-anh-minh-hoa-dau-cong
Nút dấu cộng khi kéo block ra editor
wordpress-gutenberg-anh-minh-hoa-block
Hiện bạn chọn block thêm vào khi bấm nút dấu cộng

Sau khi tìm hiểu xong cách dùng cơ bản, chúng ta sẽ đi chi tiết hơn về các option mà WordPress hỗ trợ chúng ta trong Component InnerBlock này. Các setup trong InnerBlock của WordPress

allowedBlocks

Với props này chúng ta có thể giới hạn được block mà người dùng chọn để thêm vào block của chúng ta. Ví dụ:

const ALLOWED_BLOCKS = [ 
                         'core/image', 
                         'core/paragraph', 
                         'core/heading',
                         'core/embed'
                       ];
...
<InnerBlocks
    allowedBlocks={ ALLOWED_BLOCKS }
/>

Ở ví dụ này thì người dùng chỉ có thể thêm được block image, văn bản, tiêu đề và các block để nhúng iframe vào như youtube, wordpress,…

template

Với props này chúng ta có thể setup template mà các bạn muốn lúc kéo block ra. Vú dụ mình muốn block kéo ra sẽ có hình ảnh và chữ mô tả / tiêu đề thì props này phù hợp với mục đích đó. Mình ví dụ cách để setup như sau:

const TEMPLATE = [ 
   ['core/image',{}],
   ['core/paragraph', { placeholder: 'mô tả về hình ảnh của bạn ' }],
   ['core/heading', { placeholder: ' Tiều đề hình ảnh' },level: 3],
];
...
<InnerBlocks
    template={ TEMPLATE }
/>

Với ví dụ trên mình setup để người cùng có kéo block ra sẽ có các block con bên trong gồm image, văn bản có placeholder như trên code block và tiêu đề có placeholder với thẻ tag h3 cho tiêu đề.

templateLock

Với props này các bạn có thể cho phép người dùng có thể thêm block hoặc xoá block hay không trong InnerBlock. Với props này chúng ta có 3 giá trị có thể điền vào:

  • ‘all’ — Người dùng không thể chèn các khối mới ,di chuyển các khối hiện có hoặc xóa chúng.
  • ‘insert’ — Người dùng không thể chèn hoặc xóa các khối, nhưng có thể di chuyển các khối hiện có.
  • false — cho phép người dùng có thể thêm, xoá , di chuyển các block bên trong. ( Boolean )

Kết luận

Đây là các props mình hay xài, các bạn thể tìm thêm các props khác thông qua link này

Select Control 

Đây là component giúp chúng ta tạo select field trên thanh sidebar quản lý của block, cho phép người dùng chọn giá trị.

gutenberg-wordpress-innerblock-anh-minh-hoa-select-control
Ảnh mịnh hoạ cho select control component

Với component này các bạn thêm vào như sau:

const { SelectControl,PanelBody } = wp.components
const { InspectorControls } = wp.editor
...
const onChangeColumn = ({columns}) => {
  setAttibutes({columns})
}
...
<InspectorControl> 
   <PanelBody>
     <SelectControl
            label="Số cột bạn muốn block hiển thị"
            value={ columns }
            options={ [
                { label: 'Chia 2 cột', value: 'card-profile-2-col' },
                { label: 'Chia 3 cột', value: 'card-profile-3-col' },
                { label: 'Chia 4 cột', value: 'card-profile-4-col' },
            ] }
            onChange={onChangeColumns}
        />
   </PanelBody>
</ InspectorControl>

Với đoạn code trên mình dùng để tạo select field cho phép người dùng chọn số cột hiển thị ngoài giao diện.

Tạo block Card profile grid layout

Sau khi tìm hiểu InnerBlock và và Select Control chúng ta sẽ bắt đầu làm block hiển thị grid layout cho biết viết. Chúng ta sẽ chia làm 2 phần gồm: tạo Card Profile và tạo Card profile grid layout.

Tạo card profile

Nhiều bạn chắc cũng đang thắc mắc với tiêu đề này vì chúng ta cần làm Card profile grid layout chứ không phải card profile. Tuy nhiên việc tạo Card profile giúp chúng ta có thể chia nhỏ component và tạo được trải nghiệm tốt hơn khi người dùng có thể add được Card Profile trong block trên. Chúng ta bắt đầu register block và khai báo các attribute cần dùng trong block này

const {registerBlockType} = wp.blocks
const {useBlockProps,InnerBlocks} = wp.blockEditor
//import { useBlockProps,InnerBlocks } from '@wordpress/block-editor';
//import { registerBlockType } from '@wordpress/blocks'

registerBlockType('wolfactive/card-profile', { 
   title: "Card Profile", 
   description: "Card Profile dùng cho Card profile grid layout", 
   category: "wolfactive", 
   attributes: {},
   icon: "wordpress",
   parent: "wolfactive/card-profile-grid-layout", 
   // phần này khai báo với wordpress chỉ được dùng block này 
   // khi được thêm vào block Card profile grid layout 
   keywords:["wolfactive","card",profile"], 
   edit: ({attributes, setAttributes}) => {
       const blockProps = useBlockProps();
       return <div { ...blockProps }> 
                <div className="wa-card-profile">
                  <InnerBlocks 
                    allowedBlocks={['core/image','core/heading','core/paragraph']}
                    template={[
                      ['core/image',{}],
                      ['core/heading',{placeholder: "Họ và tên",level: 3}],
                      ['core/paragraph',{placeholder: "Nghề nghiệp"}] 
                    ]}
                    templateLock={"all"}
                 />
                </div>
              </div>
   }, 
   save: ({attributes}) => {
       const blockProps = useBlockProps.save();

		return (
			<div { ...blockProps }>
               <div className="wa-card-profile">
				 <InnerBlocks.Content />
               </div>
			</div>
		);
   } 
})

Tạo card profile grid layout

Sau khi tạo xong Card profile chúng ta bắt đầu tạo block Card profile grid layout.

const {registerBlockType} = wp.blocks
const {useBlockProps,InnerBlocks} = wp.blockEditor
//import { useBlockProps,InnerBlocks } from '@wordpress/block-editor';
//import { registerBlockType } from '@wordpress/blocks'

registerBlockType('wolfactive/card-profile-grid-layout', { 
   title: " Card profile grid layout", 
   description: " Card profile grid layout dùng cho Card profile grid layout", 
   category: "wolfactive", 
   attributes: {
     "columns" : {
       "type": "string" 
     }
   },
   icon: "wordpress",
   // phần này khai báo với wordpress chỉ được dùng block này 
   // khi được thêm vào block Card profile grid layout 
   keywords:["wolfactive","card",profile"], 
   edit: ({attributes, setAttributes}) => {
       const blockProps = useBlockProps();
       let {columns} = attributes
       const onChangeColumn = ({columns}) => {
         setAttibutes({columns})
       }
       return <div { ...blockProps }>
                <InspectorControl>
                  <PanelBody>
                    <SelectControl
                       label="Số cột bạn muốn block hiển thị"
                       value={ columns }
                       options={ [
                          { label: 'Chia 2 cột', value: 'card-profile-2-col' },
                          { label: 'Chia 3 cột', value: 'card-profile-3-col' },
                          { label: 'Chia 4 cột', value: 'card-profile-4-col' },
                       ] }
            onChange={onChangeColumns}
        />
                  </PanelBody>
                </InspectorControl>
                <div className="wa-card-profile-grig-layout">
                   <InnerBlocks 
                    allowedBlocks={['wolfactive/card-profile']}
                  />
                </div>
              </div>
   }, 
   save: ({attributes}) => {
       const blockProps = useBlockProps.save();
       let {columns} = attributes
		return (
			<div { ...blockProps }>
               <div className={`wa-card-profile-grig-layout ${columns}`}>
                   <InnerBlocks.Content />
                </div>
			</div>
		);
   } 
})

Vậy là chúng ta đã làm xong việc vận dụng 2 components trên để tạo block Card profile grid layout. Hiện gặp các bạn ở bài viết kỳ tới.