פיתוח אתרים עם AI
דברו איתי WPSITE.CO.IL

וורדפרס

Bedrock לוורדפרס: Composer, Git ומבנה פרויקט מסודר

אם אתם בונים אתרי וורדפרס ומכניסים את כל ההתקנה ל-Git, git status עלול להציג אלפי קבצים: הליבה, תוספים, תבניות והעלאות לצד הקוד שלכם. בלי מבנה ו-.gitignore מתאימים, קשה לראות מה באמת השתנה.

זה לא באג של Git. המדריך הזה הוא על Bedrock של Roots (נפתח בלשונית חדשה), שמאפשר לנהל WordPress כפרויקט PHP עם dependencies מוגדרים, גרסאות נעולות והגדרות נפרדות לכל סביבה. אם Git עדיין חדש לכם, התחילו במדריך Git לפרילנסרים בוורדפרס.

זה לא מדריך למתחילים. הוא מיועד למי שכבר בונה אתרי WordPress ומכיר שורת פקודה, Git ו-Composer. אם אתם עדיין בונים את האתר הראשון שלכם, חזרו ל-Bedrock אחרי שתכירו את המבנה הרגיל.

הכאב של וורדפרס “רגיל”

הדרך הקלאסית, להוריד zip, להעתיק wp-content, להעלות עם Duplicator, עובדת מצוין כל עוד אתם לבד ובלי דפלוי מסודר. ברגע שעוברים לעבודה מקצועית, היא מתחילה לכאוב בארבעה מקומות:

  • הכול מעורבב. ליבה, תוספים, תבניות, העלאות והקוד שלכם יושבים באותה תיקייה. אין קו ברור בין מה שכתבתם לבין מה שהורדתם.
  • Git מאבד משמעות. commit של אתר שלם = אלפי קבצי ליבה ועוד כל התוספים. עדכון תוסף אחד מייצר diff ענק של קוד שלא כתבתם ולא תקראו לעולם.
  • אין תיעוד של מה מותקן. איזו גרסת WooCommerce רצה? התשובה היחידה היא “תיכנס לתיקייה ותסתכל”. שחזור מדויק של אותו אתר במקום אחר הוא עבודת יד שבירה.
  • ניהול סודות ידני. בהתקנה קלאסית פרטי מסד הנתונים נמצאים בדרך כלל ב-wp-config.php. אם הקובץ נכנס ל-Git הסודות נחשפים; אם עורכים אותו ידנית בכל שרת, קל ליצור פערים. הקובץ גם נמצא לעיתים תחת ה-document root ותלוי בהגדרת השרת.

ועוד נקודה שמכאיבה בדפלוי: אותו wp-config.php הוא זהה בכל מקום. הוא לא יודע להבדיל בין המחשב המקומי שלכם, שרת ה-staging והייצור, אלא אם תזריקו לו פריצות מסוג if (localhost). זה עובד, אבל זה מלוכלך.

הרעיון המרכזי: וורדפרס כ-dependency

ההיגיון שמאחורי Bedrock הוא אחד, וזה העיקר:

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

במקום לשמור ב-repo אלפי קבצי ליבה, שומרים קובץ טקסט קטן שאומר “האתר הזה משתמש בוורדפרס בגרסה X, ב-WooCommerce בגרסה Y, ובתבניות האלה”. כלי בשם Composer קורא את הרשימה ומוריד את הקבצים בפועל, לפי דרישה.

מי שעבד עם Docker יזהה כאן רעיון דומה: ההגדרה היא מקור האמת, ואת התלויות אפשר לשחזר ממנה. ה-repository שומר את הקוד שלכם, קובצי התצורה, composer.json, composer.lock וקבצים נוספים שנדרשים לבנייה, בלי לעקוב אחרי כל קובצי הליבה והתוספים שמנוהלים ב-Composer.

Composer הוא מנהל החבילות של PHP, בדיוק כמו ש-npm הוא מנהל החבילות של Node. אם עבדתם עם npm, התחושה תהיה מוכרת מאוד.

מבנה התיקיות, ולמה כל דבר זז

המבנה של Bedrock נראה מוזר במבט ראשון, אבל הוא הגיוני לגמרי. נשווה אותו לקלאסי:

וורדפרס קלאסי, מה שכולנו מכירים:

public_html/ ← כל זה הוא ה-web root הציבורי
├── wp-admin/ wp-includes/ ← הליבה
├── wp-content/{themes,plugins,uploads}
├── wp-config.php ← config + סיסמת DB, הכול כאן
└── index.php

הליבה, הקוד, ההעלאות וה-config נמצאים בדרך כלל תחת אותו document root. שרת שמוגדר כראוי אינו מציג את תוכן wp-config.php, אך המבנה עדיין נשען על הגנת השרת ועל ניהול זהיר של הקובץ.

ועכשיו Bedrock:

bedrock-lab/ ← שורש הפרויקט (לא נגיש מהדפדפן)
├── composer.json / composer.lock ← רשימת dependencies + נעילת גרסאות
├── vendor/ ← ספריות PHP של Composer
├── config/
│ ├── application.php ← מחליף את רוב wp-config.php
│ └── environments/ ← development.php, staging.php ודריסות נוספות לפי הצורך
├── .env ← סודות + DB, מחוץ ל-web root
└── web/ ← ה-WEB ROOT (רק זה ציבורי)
├── wp/ ← ליבת וורדפרס כאן
├── app/ ← זה wp-content, בשם אחר
│ └── {themes,plugins,mu-plugins,uploads}
└── index.php wp-config.php ← bootstrap זעיר

שלוש הזזות, וכל אחת פותרת אחת מהבעיות שלמעלה.

web root נפרד. ב-Bedrock רק תיקיית web/ מוגשת על ידי השרת. composer.json, תיקיית vendor/, תיקיית config/ וקובץ .env יושבים מעליה. כך הסודות אינם תלויים רק בכך שהשרת יפרש PHP כראוי, והסיכון לחשיפה עקב הגדרה שגויה מצטמצם.

הליבה עוברת ל-web/wp/, ליבה כ-dependency מתחלף. הליבה מבודדת בתת-תיקייה משלה, מותקנת ומעודכנת באמצעות Composer ואינה נכנסת ל-Git. עדכון WordPress נעשה בפקודת Composer ממוקדת, אחריה בודקים את האתר ושומרים את השינויים ב-composer.json וב-composer.lock. בגלל ההזזה הזו, ה-front-end נמצא ב-/ אבל לוח הבקרה יושב ב-/wp/wp-admin.

wp-content הופך ל-web/app/, הקוד שלכם, מופרד בבירור. מבחינה פונקציונלית זו אותה תיקייה בדיוק: אותם themes/, plugins/, mu-plugins/, uploads/. השם שונה ל-app כדי לסמן “האפליקציה שלכם” מול מנוע הליבה ב-wp/. ערכת בלוקים FSE נכנסת ל-web/app/themes/ ועובדת רגיל לחלוטין.

composer.json מול composer.lock, כוונה מול מצב בפועל

זה החלק השימושי ביותר בפועל. אחרי הקמת פרויקט Bedrock, הוספת תוסף נראית כך:

חלון טרמינל
ddev composer require wp-plugin/classic-editor

מאיפה מגיע ה-wp-plugin/? Bedrock הנוכחי מגיע מוגדר עם WP Packages (נפתח בלשונית חדשה), מאגר Composer של Roots שעוטף את ספריית התוספים והתבניות הרשמית של WordPress.org. לכן אין צורך להוסיף WPackagist לפרויקט חדש.

זה המחליף של “Add New → Upload Plugin”. שלושה דברים קורים אוטומטית: השורה נוספת ל-composer.json, Composer מוריד את התוסף ושם אותו ב-web/app/plugins/classic-editor/, והגרסה המדויקת נכתבת ל-composer.lock. שני הקבצים האלה הם מערכת אחת, ושניהם נכנסים ל-Git:

  • composer.json מחזיק את הכוונות שלכם כטווחי גרסאות. "^1.6" אומר “גרסה 1.6 או כל 1.x מאוחרת יותר”. פקודות כמו composer require ו-composer remove מעדכנות אותו עבורכם; אין צורך לערוך אותו ביד ברוב הפעולות השגרתיות.
  • composer.lock מחזיק את הגרסאות המדויקות שהותקנו בפועל, למשל 1.6.7. הוא נוצר על ידי המכונה, והוא snapshot מדויק של מצב האתר.

ההפרדה הזו פותרת בדיוק את הדאגה מ”עדכונים מסובכים”. יש שתי פקודות:

חלון טרמינל
ddev composer install
ddev composer update wp-plugin/classic-editor --with-dependencies

install מתקין את הגרסאות המדויקות שב-composer.lock. ב-deploy אפשר להריץ אותו בשרת או לבנות artifact מראש, לפי התשתית. update רץ בזמן פיתוח על חבילה מוגדרת, אחריו בודקים את האתר ושומרים ב-Git את composer.json ואת composer.lock.

צילום מסך של פלט הפקודה composer require בטרמינל, השורה שנוספת ל-composer.json והגרסה שננעלת ב-composer.lock
פלט הטרמינל של composer require, השורה שנוספת ל-composer.json והגרסה שננעלת ב-composer.lock.

נקודה אחת שמבלבלת בהתחלה: Composer מתקין קבצים, אבל לא מפעיל תוספים. Composer מנהל את הקבצים, מוריד, מעדכן, מסיר. וורדפרס ממשיך לנהל את המצב, פעיל או לא פעיל, הגדרות. אחרי composer require, אתם מפעילים את התוסף כרגיל, או מ-WP-CLI או מלוח הבקרה:

חלון טרמינל
ddev wp plugin activate classic-editor

DISALLOW_FILE_MODS: למה כדאי לכבות התקנות מלוח הבקרה

בתוך config/application.php יושבות שתי שורות שמשנות את ההתנהגות באופן המורגש ביותר:

Config::define('DISALLOW_FILE_EDIT', true); // אין עורך קוד בלוח הבקרה
Config::define('DISALLOW_FILE_MODS', true); // אין התקנה או עדכון מלוח הבקרה

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

בסביבה המקומית אפשר להגדיר ב-config/environments/development.php את DISALLOW_FILE_MODS ל-false. גם אז, כל תוסף שאמור להישאר בפרויקט צריך להיכנס דרך composer require, אחרת הוא לא יתועד ולא יגיע לפריסה הבאה.

שלושת קבצי ה-config

בוורדפרס רגיל, ה-wp-config.php עושה שלוש עבודות בו-זמנית: מחזיק סודות, מחזיק הגדרות, ומנסה להתנהג שונה לפי סביבה. Bedrock מפצל את שלוש העבודות לשלושה מקומות, וזה מה שהופך את הדפלוי לבטוח.

  • .env, סודות וערכים פר-מכונה. כאן יושב כל מה ששונה בין סביבות או סודי: פרטי מסד הנתונים, כתובת האתר, ערך WP_ENV, ה-salts, מפתחות API. הקובץ יושב מעל ה-web root, והוא נמצא ב-.gitignore. לכל סביבה, המחשב שלכם, staging, production, יש .env משלה עם הערכים שלה. הקובץ הזה לעולם לא נכנס ל-Git.
  • config/application.php, הגדרות משותפות. כאן נמצאות ברירות המחדל, ובהן התיקייה app, הליבה ב-wp והגדרות שמתאימות לייצור. הקובץ קורא ערכים דרך helper בשם env(), כך שהקוד נשאר גנרי והסוד נשאר ב-.env. הקובץ הזה נכנס ל-Git.
  • config/environments/development.php ו-staging.php, דריסות פר-סביבה. Bedrock טוען קובץ ששמו תואם ל-WP_ENV רק אם הוא קיים. אין חובה ליצור production.php, משום שברירות המחדל נמצאות ב-application.php.

התוצאה: מעבר מהמחשב המקומי לייצור לא נוגע באף שורת קוד. רק קובץ ה-.env שונה בשרת. אותו קוד רץ בכל מקום, ורק ה-.env משתנה, וזו בדיוק הסיבה שדפלוי מבוסס-Git הוא בטוח, כי הסודות לעולם לא נוסעים דרך Git.

על ה-salts, ברצינות

ב-.env.example יש שמונה שורות salts עם הערך generateme. אלה מפתחות וסודות ש-WordPress משתמש בהם לחתימה ולאימות של עוגיות ונתוני התחברות. במחשב המקומי אתר יעלה גם עם ערכי הדמה, אבל לפרויקט אמיתי צריך לייצר ערכים ייחודיים. מחולל ה-salts של Roots (נפתח בלשונית חדשה) מחזיר פלט מוכן בפורמט .env.

צילום מסך של הדף roots.io/salts.html עם שמונה שורות salts בפורמט env מוכנות להעתקה
הדף roots.io/salts.html עם שמונה שורות ה-salts המוכנות להעתקה ל-.env.

Bedrock זה לא Sage (וזה לא Trellis)

הרבה אנשים מתבלבלים בין שלושת הכלים של Roots, אז נסדר את זה. Bedrock, Sage ו-Trellis הם שלושה כלים נפרדים של אותה קבוצה, ואנשים נוטים לערבב ביניהם.

Bedrock נוגע אך ורק לתשתית: מבנה התיקיות, ה-config, ניהול ה-dependencies. הוא לא נוגע, ולו במעט, לאופן שבו אתם בונים את התבנית עצמה. Sage, לעומתו, הוא starter theme שכן משנה את אופן בניית התבנית, לכיוון מנוע תבניות בשם Blade ובניית theme קלאסית, לא-FSE.

לכן המשפט החשוב: אפשר להשתמש ב-Bedrock עם ערכת בלוקים FSE לגמרי בלי Sage. Bedrock ו-FSE פועלים בצירים שונים. Bedrock מטפל ב”איפה הקבצים יושבים ואיך מתקינים אותם”; FSE מטפל ב”איך בונים את העיצוב”. אתם מכניסים ערכת בלוקים FSE לתיקיית web/app/themes/ של פרויקט Bedrock, והיא עובדת בדיוק כמו בכל וורדפרס אחר. ככה אני עובד יום-יום: Bedrock כתשתית, FSE כשכבת העיצוב, בלי Sage באמצע.

הקמה מקומית עם DDEV

צריך DDEV ומנוע קונטיינרים נתמך. Docker Desktop הוא אפשרות אחת, אבל אינו חובה. את אפשרויות ההתקנה ל-macOS ול-Windows תמצאו במדריך לסביבת WordPress מקומית.

אחרי שמנוע הקונטיינרים פועל:

חלון טרמינל
mkdir -p my-wp-bedrock-site && cd my-wp-bedrock-site
ddev config --project-type=wordpress --docroot=web
ddev start
ddev composer create-project roots/bedrock
mv .env.example .env

עכשיו מעדכנים ב-.env את חיבור מסד הנתונים ואת כתובות האתר המקומי. שאר הערכים, ובהם ה-salts, נשארים חלק מהגדרת הסביבה שלכם:

DB_NAME=db
DB_USER=db
DB_PASSWORD=db
DB_HOST=db
WP_HOME=${DDEV_PRIMARY_URL}
WP_SITEURL=${WP_HOME}/wp
WP_ENV=development

לאחר שמירת הקובץ מתקינים את WordPress:

חלון טרמינל
ddev wp core install \
--url='$DDEV_PRIMARY_URL' \
--title='My Bedrock Site' \
--admin_user=admin \
--prompt=admin_password

הפקודה create-project מורידה את שלד Bedrock ואת התלויות. ערכי ה-.env שייכים לפרויקט וצריך להתאים אותם לכל סביבה; הם אינם נכנסים ל-Git. הפקודה האחרונה מתקינה את WordPress בלי לשמור את סיסמת המנהל בהיסטוריית ה-shell.

אז למה זה משנה

קחו צעד אחורה ותראו מה השתנה. ה-repo שלכם מכיל עכשיו רק קוד שכתבתם, רשימת dependencies, וקבצי config. git status מראה לכם בדיוק את העבודה שלכם, נקייה. גרסת כל תוסף מתועדת ונעולה. הסודות יושבים מחוץ ל-Git ומחוץ לתיקייה הציבורית. ואותו קוד בדיוק רץ במחשב שלכם, ב-staging ובייצור, כשרק קובץ סודות אחד משתנה ביניהם.

מעבר למבנה התיקיות, Bedrock משנה את הדרך שבה חושבים על אתר WordPress. אחרי שעובדים כך תקופה, חזרה ל-wp-content שמעתיקים ב-FTP מרגישה כמו לעבוד בלי רשת ביטחון. ההשקעה בהבנת המבנה מחזירה את עצמה בכל פריסה ועדכון.

תגובות

טוען תגובות…

השארת תגובה

התגובות עוברות אישור לפני הפרסום.

בואו נעבוד יחד

אני בונה אתרים ומוצרים עם AI, מלווה צוותים בתהליכי עבודה ומעביר הרצאות וסדנאות.

דברו איתי