349
44

[ WordPress ] Tạo block Gutenberg sử dụng MediaPlaceHolder và RichText

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

Chào các bạn cũng lâu rồi nhỉ? Mình mới viết thêm blog mới chia sẻ kinh nghiệm làm việc cũng như kỹ năng lập trình của team với mọi người. Với bài viết kỳ này team mình đem đến màu blog mới cũng như theo xu hướng hiện giờ WordPress đang phát triển theo – Gutenberg.

Khái quát về components và tạo blocks sử dụng MediaPlaceHolder, RichText

Để các bạn hiểu rõ hơn những gì Gutenberg mang lại đối với lập trình viên WordPress, team mình hướng dẫn các bạn sử dụng Media PlaceHolder và RichText của WordPress. Về phần setup để bắt đầu viết block các bạn có thể xem ở bài [Gutenberg ] Tạo Block Gutenberg đầu tiên

Media placeholder component là gì ?

wordpress-gutenberg-mediaplaceholder
Media placeholder là component của Gutenberg WordPress, hỗ trợ developer có thể tạo field chọn hình ảnh của user trong khung giao diện block editor. Component cho phép user có thể upload từ máy tình hoặc import ảnh từ url bất kỳ, ngoài ra user cũng có thể chọn ảnh từ media của website.

Để sử dụng component chúng ta cần phải import Component từ wordpress như block code sau:

const { MediaPlaceholder } = wp.blockEditor
// Hoặc có thể import như sau:
// import { MediaPlaceholder } from '@wordpress/block-editor';
...
edit: ( { attributes, setAttributes } ) => {
return <>
    <MediaPlaceholder
    onSelect = {
                ( el ) => {
                    setAttributes( { theImage: el.url } );
                }
            }
            allowedTypes = { [ 'image' ] }
            multiple = { false }
            labels = { { title: 'The Image' } }
    />
</>
}

Mình giải thích rõ hơn về các props trong component này:

accept

Đây là props để chúng ta define được loại media nào được upload lên ví dụ: image/*,video/*.

allowedTypes

Props này giúp chúng ta có thể cho phép user upload các dạng file media( picture, text, video,… ) ví dụ: audio/mpeg, image/gif.

className

Props này giúp chúng ta đặt class cho PlaceHolder để tiện styling hoặc viết js.

multiple

Props này giúp chúng ta cho phép user upload và chọn được nhiều hay 1 file ảnh trong 1 lần chọn.

onError

Props này sẽ gọi callback function để xử lý khi upload file bị lỗi

onFilesPreUpload

Props này sẽ gọi callback function để xử lý trước khi file ảnh được upload vào media

onSelect

Props này để gọi callback sau khi file được upload lên media manager của wordpress.

value

Props này để register variables của media.

onSelectURL

Props này để xử lý sau khi user nhập image URL vào field.

Đây là 1 số props mình thấy hay dùng tới ngoài ra còn một số props khác các bạn có thể tra cứu tại đây.

RichText Component là gì ?

RichText là là component của Gutenberg WordPress, hỗ trợ developer có thể tạo field cho phép user nhập text, 1 đoạn văn bản hoặc nhiều đoạn văn bản,… với các tính năng chỉnh text như, căn lề, in nghiêng chữ, in đậm chữ, ganh dưới chữ,…
Để sử dụng component chúng ta cần phải import Component từ wordpress như block code sau:

const { RichText } = wp.blockEditor
// Hoặc có thể import như sau:
// import { RichText } from '@wordpress/block-editor';
attributes: {
        content: {
            type: 'string',
            source: 'html',
            selector: 'h3',
        },
    },
// Các thể có thể selector: p, h1, h2, h3, h4, h5, h6, span
    edit( { className, attributes, setAttributes } ) {
        return (
            <RichText
                tagName="h3"
                className={ className }
                value={ attributes.content }
                onChange={ ( content ) => setAttributes( { content } ) }
            />
        );
    },

    save( { attributes } ) {
        return <RichText.Content tagName="h3" value={ attributes.content } />;
    }
}

Mình giải thích rõ hơn về các props trong component này:

tagName

Đây là props để chúng ta define selector của RichText, và việc define này phải giống hoàn toàn với giá trị chúng ta đã khai báo ở attributes

className

Tương tự như Component trên thì props này để đat class cho selector của RichText lúc render ở editor admin và frontend.

onChange

Đây là props sẽ gọi callback function handle khi user nhập ký tự vào fields

placeholder

Đây là props thêm placeholder vào RichText

multiline

Props này chúng ta có thể phép user nhập text thành nhiều hàng hoặc không.

Đây là 1 số props mình thấy hay dùng tới ngoài ra còn một số props khác các bạn có thể tra cứu tại đây.

Tạo block CTA card

Trước tiên chúng ta cần phải register block với wordpress thông qua hàm registerBlockType

const { registerBlockType } = wp.blocks
const { __ } = wp.i18n
//import { registerBlockType } from '@wordpress/blocks'

registerBlockType(slug, {
            title: 'CTA Wolfactive block',
            description: 'This CTA Wolfactive block for my website',
            category: 'wolfactive',
            icon: 'dashicons-admin-site',
           keywords: [
                __('cta', 'wolfactive'),
                __("Wolfactive", 'wolfactive'),
                __('Home', 'wolfactive'),
            ],
            attributes:{

            },
            edit: function({ attributes, setAttributes }){

            },
            save: function({ attributes }){

            },
        })

Sau khi các bạn refesh lại editor thì các bạn sẽ thấy block đã tạo ví dụ như hình ảnh sau:

gutenbergs-cta-block-wolfactive

Tiếp theo chúng ta đi tiếp các tạo function cho edit. Đây là function để render component cũng như các tính năng điều chỉnh block trong editor của admin

const { registerBlockType } = wp.blocks
const { __ } = wp.i18n
const {Spinner} = wp.components
const {isBlobURL} = wp.blob
const {RichText, InspectorControls,MediaPlaceholder} = wp.blockEditor

//import { registerBlockType } from '@wordpress/blocks'
//import { __ } from '@wordpress/i18n'
//import {isBlobURL} from "@wordpress/blob";
//import {Spinner} from "@wordpress/components";
//import {RichText, InspectorControls,MediaPlaceholder} from "@wordpress/blockEditor";

registerBlockType(slug, {
            title: 'CTA Wolfactive block',
            description: 'This CTA Wolfactive block for my website',
            category: 'wolfactive',
            icon: 'dashicons-admin-site',
           keywords: [
                __('cta', 'wolfactive'),
                __("Wolfactive", 'wolfactive'),
                __('Home', 'wolfactive'),
            ],
            attributes:{
                    title:{
                        type: 'string',
                        source: 'html',
                        selector: 'h2',
                    },
                    image:{
                        type:'object',
                        default:{
                            url: '',
                            id:'',
                            alt:''
                        }
                    },
                buttonContext:{
                        type: 'string',
                        source: 'html',
                        selector: 'h2',
                    },
                    buttonURL:{
                        type:'string',
                    }
            },
            edit: function({ attributes, setAttributes }){
                const {title,image,buttonURL,buttonContext} = attributes
                return <>
                    <InspectorControls>
                        <PanelBody>
                        <URLInput
                            value={ buttonURL }
                            onChange={ ( url ) => setAttributes( { buttonURL: url || 'Click here' } ) }
                        />
                        </PanelBody>
                </InspectorControls>
                    <div className="wa-cta">
                        <div className="wa-cta__container wa-container">
                            {image.url ?
                                        <>
                                            <div className={`wa-cta__image wp-image-${image.id}`}>
                                                <img src={image.url} alt={image.alt} />
                                            </div>
                                            {isBlobURL(image.url) &&  <Spinner/>}
                                        </>
                                        :
                                        <MediaPlaceholder
                                            icon="format-image"
                                            onSelect={({id, url,alt}) => setAttributes({image: {
                                                url: url,
                                                id:id,
                                                alt:alt
                                            }})}
                                            onError={error => console.log(error)}
                                            accept="image/*"
                                            allowedTypes={['image']}
                                        />
                                    }
                            <RichText
                                tagName={'h3'}
                                className="wa-cta__heading"
                                onChange={(title)=> setAtrributes({heading})}
                                value={title}
                                placeholder={__('Enter Title...', 'wolfactive')}
                                keepPlaceholderOnFocus={true}
                            />
                           <div className=""wa-cta__btn" >
                                        <a href={buttonURL}
                                           className=""wa-primary-button"
                                        >
                                            <RichText
                                                tagName={'span'}
                                                className=""
                                                onChange={(buttonContext)=> setAtrributes({buttonContext})}
                                                value={buttonContext}
                                                placeholder={__('Enter Context Button...', 'wolfactive')}
                                                keepPlaceholderOnFocus={true}
                                            />
                                        </a>
                                    </div>
                        </div>
                    </div>
                    </>
            },
            save: function({ attributes }){

            },
        })

Ở đây mình tạo các biến để lưu dữ liệu gồm title, image, buttonURL và buttonContext. Sau đó mình import thêm InspectorControl và PanelBody để chèn thêm field nhập URL cho button thông qua component URLInput, các bạn có thể đọc doument về component tại đây.

Sau cùng thì chúng ta đền phần save vào database của block:

const { registerBlockType } = wp.blocks
const { __ } = wp.i18n
const {Spinner} = wp.components
const {isBlobURL} = wp.blob
const {RichText, InspectorControls,MediaPlaceholder} = wp.blockEditor

//import { registerBlockType } from '@wordpress/blocks'
//import { __ } from '@wordpress/i18n'
//import {isBlobURL} from "@wordpress/blob";
//import {Spinner} from "@wordpress/components";
//import {RichText, InspectorControls,MediaPlaceholder} from "@wordpress/blockEditor";

registerBlockType(slug, {
            title: 'CTA Wolfactive block',
            description: 'This CTA Wolfactive block for my website',
            category: 'wolfactive',
            icon: 'dashicons-admin-site',
           keywords: [
                __('cta', 'wolfactive'),
                __("Wolfactive", 'wolfactive'),
                __('Home', 'wolfactive'),
            ],
            attributes:{
                    title:{
                        type: 'string',
                        source: 'html',
                        selector: 'h2',
                    },
                    image:{
                        type:'object',
                        default:{
                            url: '',
                            id:'',
                            alt:''
                        }
                    },
                buttonContext:{
                        type: 'string',
                        source: 'html',
                        selector: 'h2',
                    },
                    buttonURL:{
                        type:'string',
                    }
            },
            edit: function( ){},
            save: function({ attributes }){
                 const {title,image,buttonURL,buttonContext} = attibutes;
                return <>
                    <div className="wa-cta">
                        <div className="wa-cta__container wa-container">
                            {image.url &&
                                        <>
                                            <div className={`wa-cta__image wp-image-${image.id}`}>
                                                <img src={image.url} alt={image.alt} />
                                            </div>
                                            {isBlobURL(image.url) &&  <Spinner/>}
                                        </>
                                    }
                            <RichText
                                tagName={'h3'}
                                className="wa-cta__heading"
                                value={title}
                            />
                           <div className=""wa-cta__btn" >
                                        <a href={buttonURL}
                                           className=""wa-primary-button"
                                        >
                                            <RichText.Content
                                                tagName={'span'}
                                                className=""
                                                value={buttonContext}
                                            />
                                        </a>
                                    </div>
                        </div>
                    </div>
                    </>
            },
        })

Kết luận

Vậy là mình đã giải thích và hướng dẫn các bạn sử dụng 2 component MediaPlaceholder và RichText trong việc tạo custom gutenbergs block. Cảm ơn các bạn đã theo dõi, hẹn gặp các bạn vào bài tới.

44 thoughts on “[ WordPress ] Tạo block Gutenberg sử dụng MediaPlaceHolder và RichText

  1. A fascinating discussion is worth comment. I do believe that you should write more about this subject matter, it may not be a taboo subject but typically folks dont talk about such issues. To the next! Cheers!!

  2. את המקום עיצבו אדריכל גיא ארבל
    ממשרד אורן אדריכלים ואורנית שטרית
    מבעלי מלון קדם. הדיסקרטיות נשמרת
    במקרים רבים גם בנושא התשלום, אם התשלום מתבצע
    באשראי, הוא יופיע בחיובים תחת שם שלא יסגיר את המקום.
    המקום לפתרונות ישיבה היכנסו והתרשמו
    בעצמכם. ר אראלה למדן מאמנת אישית מוסמכת
    ובעלת ניסיון רב בתחום – לפרטים נוספים
    היכנסו לאתר. באתר תוכלו להזמין קריקטורה בהתאמה אישית מצייר אמיתי ולקבלה ישירות לתיבת המייל שלכם.

    באתר תוכלו למצוא בגדים לכלבים, רצועות הולכה מעוצבות וקולרים
    יפייפים במחירים שווים לכל כיס! ח ניירת משרדית,
    פנקסי חשבוניות וכל דברי הדפוס במחירים הזולים בארץ.
    פיצפקעס ברשת מביאה לכם כלי בית, פטנטים
    לבית ולמשרד ומתנות מיוחדות במחירים ללא תחרות.
    באתר תוכלו למצוא מגוון פתרונות שינה איכותיים לבית .
    מגוון רחב של נערות ליווי ברמת גן ברמה גבוהה
    ביותר 24/7 לביתך או לבית מלון ברמת גן בתמונות אמיתיות לחלוטין.
    מפחד שהתמונות לא אמיתיות? התייעצות עם אנשי מקצוע: אם יש יצא
    לכם להסתייע בעבר באנשי מקצוע מתחומים מקבילים באזור,
    כמו למשל רפלקסולוגים, מעסים רפואיים ומטפלים אלטרנטיביים בשיטות שונות, תוכלו בהחלט לשאול אותם לגבי עיסוי ארוטי בהרצליה ואם הם
    אכן מכירים מקום כזה, סביר להניח שזה יהיה
    מקום מקצועי שייתן לכם שירות
    טוב. התייעצות עם אנשי מקצוע: אם יש יצא לכם להסתייע בעבר
    באנשי מקצוע מתחומים מקבילים באזור, כמו למשל רפלקסולוגים,
    מעסים רפואיים ומטפלים אלטרנטיביים בשיטות שונות, תוכלו בהחלט לשאול אותם לגבי עיסוי ארוטי בראשון לציון ואם הם אכן מכירים מקום כזה, סביר להניח שזה יהיה מקום מקצועי שייתן לכם שירות
    טוב.

  3. I don’t even know how I ended up here, but I thought this post
    was good. I don’t know who you are but certainly you are
    going to a famous blogger if you aren’t already 😉 Cheers!

    Also visit my web site anleitung spielautomat las vegas [Estella]

  4. Hello There. I found your blog using msn. This is a very well written article.
    I’ll make sure to bookmark it and come back
    to read more of your useful info. Thanks for the post. I will certainly return.

    My page http://www.die-rheinischen-bauern.de

  5. It’s remarkable to pay a quick visit this web site and reading the views of all mates on the topic of this piece of
    writing, while I am also keen of getting familiarity.

    Here is my web site … wild rubies Automatenspiele

  6. You really make it appear really easy along with your presentation however I find this topic to be actually something that I think I might
    by no means understand. It kind of feels too complex and extremely extensive for me.
    I am looking ahead for your subsequent put up, I’ll attempt to get the cling
    of it!

    Here is my blog post; tips gokkasten holland casino – Cliff

  7. Your method of describing the whole thing in this post
    is really fastidious, all can without difficulty know it, Thanks a lot.

    Have a look at my web page poker toernooi holland casino
    nijmegen – Curtis

  8. [url=https://lyrica.icu/]lyrica 400 mg[/url]

  9. certainly like your web site but you have to take a look at the spelling on several of your
    posts. Many of them are rife with spelling issues and I
    to find it very bothersome to inform the truth on the other hand I’ll surely come back again.

    Take a look at my web blog :: regiotime-hechingen.de

Comments are closed.