פיתוח בלוק לגוטנברג

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

מבוא

בשנת 2020 הכנתי הרצה מקיפה על מעבר לגוטנברג ברמת מערכת ניהול ושימוש בתוסף ACF. מאז עברנו די הרבה ברמה טכנולוגית בכללי והתפתות של גוטנברג בפרט. וורדרפס כבר עבר את גרסה 6.6, התייצבו ברמת Full Site Editor.

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

לפני תחילת עבודה, לפי דוקומנטציה של גוטנברג, יש צורך לדעת לעבוד עם React ויסודות של ES6. לדעתי בפיתוח פשוט אפשר להסתפק בES6 ו JSX. בבלוקים פשוטים אין צורך בריאקט, די דומה לתבניות בסיס שלא דרשו צורך בPHP אלה פונקציות מוכנות. בוורדפרס הכינו הרבה דברים מוכנים מבוססי ריאקט. ידע בריאקט מורגש נחוץ כשאר נכנסים לפיתוח מורכב יותר והתממשקות עם API של וורדפס עצמה.

התוצאה סופית

ניתן להוריד את הקוד כאן.

אפיון בלוק

אני הולך לבנות בלוק של וידאו תוך כדי התייחסות לרכיבים הבאים: וידאו מגיע מיוטיוב ואמור להתנגן אוטומטית. כמו כן תהיה אפשרות לשים תוכן מעלב ולקבוע את השקיפות של מסכה על הוידאו במידה ובוגדר מראש על ידי משתמש.

יצירת בלוק מתוך npm

ברשת יש מלא מדריכים שונים שמסבירים את העניין של יצירת בלוקים, אבל המדריך הכי טוב הוא מדריך של וורדפרס עם חבילה שמפורסמת בספריית npm. לפי דוקומנטיה נשרד להתקין nodejs במחשב ולעבוד בתיקיית התוספים. הקוד אמור ליצור תוסף חדש.

אני משתמש בPHPStorm וVSCode שניהם משתמשים בטרמינל מובנה.

 npx @wordpress/create-block@latest first-block 

לאחר תהליך התקנה, מקבלים סביבה מוכנה עם חבילות nodejs הנדרשות, בעיקר מה שמעניין אותנו זה wordpress/scripts שיהיה בגרסה אחרונה. זאת החבילה המרכזית שאחראית על כל תהליך הפיכה של הקוד שלנו לבלוק.

לאחר חיטות בתיקייה, אפשר להבין שקוד יושב בתקיית src ומחולק למספר חלקים, קובץ block.json שאחראי על כל הצד הטכני של הבלוק, קבצי JS שאחראים על הבלוק (index, edit, save), קובץ JS שנתען בפרונט (view), קבצי SCSS אחד לניהול בלבד (edit) והשני גם לניהול וגם לפרונט. בבסיס יש קובץ render.php. בגוטנברג יש שתי אפשרויות לשמירה של בלוק, בעזרת JS שאחראי לו קובץ save.js ובעזרת PHP שאחראי קובץ render.php.

אפשר לומר שבזמן פיתוח בלוקים של וורדרפס, אפשר לגמרה להתנתק מPHP ולעבוד רק עם JS בעזרת Rest API.

בתיקיה ראשית יש קובץ package.json יש את כל התלכים האפשריים. שמבחינתי בלשבי פיתוח מה שמנעיין אותי זה npm run start כדי להריץ את תהליך מעקב אחרי שינויי הקבצים.

הגדרות כלליות

בגרסאות הקודמות היה קצת חוסר סדר ברמת הגדרות, איפה כותבים מה ואיך מגדירים את המאפיינים של הבלוק. בגרסה השלישית הכול עבר לקובץ block.json, בו אפשר למצוא את כל ההגדרות ואת כל המפפיינים הנדרשים לצורך יצירה של הבלוק.

block.json
 {
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "create-block/first-block",
	"version": "0.1.0",
	"title": "First Block",
	"category": "widgets",
	"icon": "smiley",
	"description": "Example block scaffolded with Create Block tool.",
	"example": {},
	"supports": {
		"html": false
	},
	"textdomain": "first-block",
	...
} 

חשוב לבדוק שמדובר בגרסה 3 של apiVersion ולהגדיר את השמות הנכונים ברמת title המשמש לעורך תוכן וname שוורדרפס מתבסס על חלק הזה.

החלק הכי לשוב נמצא בסוף הקובץ ומגדיר לוורדרפס איך לטפל ברמת העריכה ותצוגה של הרכיב.

block.json
 {
	...,
	
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css",
	"viewScript": "file:./view.js"
} 

כמו שכתבתי קודם, יש התייחסות לתהליך הניהול של האתר והגדרות שלו ותלהיך של תצוגה. במקרה הבסיסי עדיין יש קובץ render.php שמאפשר לעבור לPHP בצורה מלאה כדי להציג תוכן. אני מעדיף לעבוד עם JS נקי ומוחק את השורה של רינדור.

בשלב הבא אני צריך לקבוע את התכונות שאני אשתמש לצורך ניהול של הבלוק. התכונות מופיעות בסוג אובייקט עם שם התכונה, טיפוס ואם יש ערך דיפולטיבי.

  • מזהה וידאו ביוטיוב – string
  • הצללה על הוידאו – boolean
  • צבע הצללה – string
  • תמונה שתחליף את הוידאו במערכת הניהול (לא חובה אבל לצורך תרגול – string
block.json
 {
	...,
	"attributes": {
		"videoId": {
		  "type": "string",
		  "default": ""
		},
		"videoImage" : {
			 "type": "string",
		  	"default": "https://placehold.co/560x315?text=Video Id"
?text=Video Id"
		},
		"videoShape" : {
			"type": "boolean",
		  "default": false
		},
		"videoShapeColor" : {
			"type": "string",
		  "default": ""
		}
	},	
	...
} 

סיימתי עם כל ההגדרות של בלוק והכול אמור לעבוד תקין. וכבר רואים את הרכיב בתוך מערכת הניהול.

המחשה של בלוק במערכת הניהול
המחשה של בלוק במערכת הניהול, אבל עם נראות בסיסית ביותר.

שינוי מערכתי

בשלב הבא החלטתתי לעשות שינוים בקובץ index כדי להוסיף עליו את קוב. save שאמור להחליף את הrender של PHP. דבר נוסף שעשיתי זה שיניתי את Edit לedit כדי לקבל נראות יותר טובה.

index.js
 ...
registerBlockType( metadata.name, {
	/**
	 * @see ./edit.js
	 */
	edit,
	/**
	 * @see ./save.js
	 */
	save,
});  

בניית רכיב עריכה

קובת עריכה הוא למעשה הקובץ העיקרי שבו כל הלוגיקה יושבת ומתוארת לצורך עריכה והכנה לשמירה. העריכה מתחלקת לשלושה חלקים: תוכן עיקרי, פאנל ניהול והגדרות וסרגל עליון של הבלוק.

בשלב הראשון נכניס פארמטר props לתוף הפונקציה של edit כדי לקבל את attributes ופונקציה לעדכון setAttributes.

edit.js
 const {attributes, setAttributes} = props; 

בלשב השני נחלץ אץ התכונות בסיסיות של בלוק בעזרת רכיב useBlockProps עם הגדרת קלאס בסיסי.

edit.js
 const {className, ...blockProps} = useBlockProps({
	className : "hero-video"
}); 

בשלב השלישי נעדכן את כל פלט שיציג את הדרישות שלנו.

edit.js
 return (
	<section className={className} { ...blockProps }>
		<img src={attributes.videoImage} width="960" height="720" />
	</section>
); 
תומצאה ראשונית

בשלב הבא צריך ליצור ניהול עבור הרכיב. לצורך זה נשתמש ברכיב מובנה InspectorControls המאפשר להשתמש בסרגל צידי. ביחד איתו נשתמש בPanelBody המאפשר להגדיר אזור עבודה בתוך הסרגל.

edit.js
 import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody } from '@wordpress/components'; 

הרכיבים הללו זמינים עכשיו לשימוש וצריך להטמיע אותם לפונקציית returrn לפני או אחרי בהקוד תצוגה שיצרנו מקודם. למעשה בתוך התגית section או מעליה. כשאר מוסיפים מעליה, חשוב לזכור על כללי ריאקט שאסור להחזיר שני אלמנטים זה לצד זה וכדאי להשתמש בFragmet.

edit.js
 return (
	<>
	<InspectorControls>
		<PanelBody title="General">
		</PanelBody>
	</InspectorControls>
	<section className={className} { ...blockProps }>
		<img src={attributes.videoImage} width="960" height="720" />
	</section>
	</>

); 

שלב הבא הוא הכי מעניין, הוספה של אזור עריכה ורכיבים של הזנת תוכן. למעשה יש לנו 3 מאפיינים גלויים ומעפיין מוסתר: שדה טקסט TextControl להכנסת וידאו, שדה בוליאני ToggleControl סוג של טוגל ושדה בחירת צבע ColorPiker עבר מסכה.

edit.js
 import { PanelBody, ColorPicker, TextControl, ToggleControl } from '@wordpress/components'; 

אחרי שעישינו ייבוא לקומפוננטות נטמיע בתוך הסרגל צידי.

edit.js
 <PanelBody title={ __( 'Block Setting', 'first-block' ) }>
	<TextControl
		label="Video ID"
		value={ attributes.videoId }
		onChange={ ( value ) => { 
			setAttributes({
				videoId: value, 
				videoImage : `https://img.youtube.com/vi/${value}/hqdefault.jpg`
				}) 
			}
		}
	/>
	<ToggleControl
		label={ __( 'Use Shaddow', 'first-block' ) }
		checked={ attributes.videoShape }
		onChange={ value => setAttributes( {videoShape: !attributes.videoShape})}
	/>
	{
		attributes.videoShape &&
		<ColorPicker
			color={attributes.videoShapeColor}
			onChange={ value => setAttributes( {videoShapeColor: value})}
			enableAlpha
			copyFormat="hex"
		/>
	}
</PanelBody> 

שלה הבא הוא להציג את כל התוכן הסופי על המסך ולקבל אינדיקציות של שינויים שנעשה.

חוזרים לsectuin שבתוך הפלט הראשוני ומשנים אותו בהתאם לצרכים שלנו, החלפת תמונה מתוך היוטיוב בהתאם לשינוי של סטרטו (במקום הצגה של סרטון עצמו) וקבייית מסכה מעל הסרטון לאחר סימון של האפרות.

edit.js
 <section className={className} { ...blockProps }>
	<div className="iframe-wrapper">
		{	
			attributes.videoShape &&
			<div className="iframe-shape" style={{backgroundColor:attributes.videoShapeColor} }></div>
		}
		<img src={attributes.videoImage} width="560" height="315" />
	</div>
</section> 

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

בניית רכיב שמירה

כאמור, יש אפשרות של שמירה בעזרת PHP ובעזרת JS. אני הלך לדבר על שמירה בעזרת JS והיא מתבצעת בקובץ save.js. אם כזה לא קיים בתיקיה, אז אפשר ליצור אותו.

העבודה במקרה הזה יחסית פשוטה, למשוך את כל התכונות של הבלוק בעזרת רכיב useBlockProps ולהשתמש במתודה שנקראת save.

save.js
 import {useBlockProps} from '@wordpress/block-editor';

export default function Save(props) {

    const {attributes : {videoId, videoShape, videoShapeColor}} = props;
    
    const {className, ...blockProps} = useBlockProps.save({
        className : "hero-video"
    });

	return (
        <section className={className} { ...blockProps }>
			<div className="iframe-wrapper">
				<iframe 
					width="560" height="315" 
					src={`https://www.youtube.com/embed/${videoId}?autoplay=1&mute=1&enablejsapi=1&loop=1&controls=0&playlist=${videoId}&rel=0`}
					title="YouTube video player" 
					frameborder="0" 
					allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" 
					allowfullscreen
					></iframe> 
                {	
                    videoShape &&
                    <div className="iframe-shape" style={{backgroundColor:videoShapeColor} }></div>
                }
			</div>
		</section>
	);
} 

סיכום ומסכנות

ללא ספק פיתוח בלוקים בסיסיים על גוטנברג הרבה יותר קל ונוח מאשר להתעסק עם קוד PHP ולהתחיל לבנות שורטקודים עם אפשרויות והגדרות.

בשוואה עם ACF Flexible content בבלוק של גוטנברג אפשר לראות תוצאות מיידיות ברמת ברמת העורך וגם ברמת טיוטה. גם בהשוואה של ACF Blocks שאני מאוד אוהב ומשתמש עד היום, בלוקים מקוריים הרבה יותר נוחים בגלל יכולת הוספת העשרה ואינטארקטיביות לתוך הבלוק. הדוגמה הפשוטה שהייתה זה אותו טוגל שבנינו, בגוטנברג הוא יותר אסטטי ויותר דינמי.

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

המחשבה היחידה שלא עוזבת אותי, מספאגטי בPHP עברנו לספטגטי בתוך JS (גם אם קוראים לזה JSX).

נ.ב. את הבלוק של PrismJS בניתי לפני כשנה וחצי לצורך התרגול והוא עובד נהדר גם לאחר מעבר לגרסה 3.

מחפשים פתרונות תכנות מקצועיים?

אם יש לך צורך בעזרה של מפתח מקצועי ומנוסה, אשמח לשמוע ממך

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *