חיפוש ]

שימוש ב Advanced Custom Fields ללא תלות ב Frontend

התוסף Advanced Custom Fields מספק ממשק פשוט וויזואלי ליצירת metaboxes. התוצאה אינטואטיבית ונוחה לעריכה על ידי הלקוח. ACF כולל מספר פונקציות למשיכת ערכי שדות בתבניות שלכם, אך אני ממליץ לא להשתמש בהן בצד הלקוח (frontend).

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

ניתן לעקוב אחר כמות השאילתות למסד הנתונים באמצעות התוסף Query Monitor. בבדיקות, מעבר מפונקציות ACF ל-get_post_meta() הוריד את מספר השאילתות מ-146 ל-22 בעמוד בודד.

שימוש ב-get_post_meta במקום get_field

אין סיבה להשתמש ב-get_field() כשאפשר להשתמש בפונקציית הליבה של וורדפרס get_post_meta().

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

עטיפת כל קריאות הפונקציות של ACF ב-function_exists() מונעת את השגיאה הקריטית, אך הגולשים עדיין לא יראו את ה-metadata שהכנסתם דרך ACF – למרות שהוא עדיין קיים במסד הנתונים.

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

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

הדוגמאות להלן מראות כיצד לשלוף נתוני ACF באמצעות get_post_meta() ו-get_option() במקום פונקציות ACF. גישה זו פשוטה עבור שדות סטנדרטיים אך דורשת הבנה של אופן האחסון של ACF עבור סוגי שדות מורכבים יותר.

Repeater Field עם get_post_meta

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

קריאה למפתח ה-meta של ה-repeater מחזירה את מספר הפריטים:

get_post_meta( get_the_ID(), 'my_videos', true );

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

$videos = get_post_meta( get_the_ID(), 'my_videos', true );
if ( $videos ) {
    for ( $i = 0; $i < $videos; $i++ ) {
        $title     = esc_html( get_post_meta( get_the_ID(), 'my_videos_' . $i . '_title', true ) );
        $video     = esc_url( get_post_meta( get_the_ID(), 'my_videos_' . $i . '_video', true ) );
        $thumbnail = (int) get_post_meta( get_the_ID(), 'my_videos_' . $i . '_thumbnail', true );

        $thumbnail = $thumbnail
            ? wp_get_attachment_image( $thumbnail, 'medium' )
            : '<img src="' . get_stylesheet_directory_uri() . '/images/default-video.png" />';

        $class = ( 0 === $i % 2 ) ? 'one-half first' : 'one-half';

        echo '<div class="' . $class . '"><a href="' . $video . '">' . $thumbnail . '</a>' . $title . '</div>';
    }
}

שימו לב שה-ACF Image field שומר את ה-attachment ID במסד הנתונים. את ה-markup של התמונה מקבלים באמצעות הפונקציה wp_get_attachment_image():

wp_get_attachment_image( $image_id, 'image_size' );

נתוני Options Page

כשמוסיפים metaboxes לעמוד Options של ACF, הנתונים נשמרים בטבלת wp_options, לא כ-post meta. המפתח הוא שם השדה עם תחילית options_.

אם בעמוד ה-Options יש שלושה שדות, שלפו אותם כך:

$title       = esc_html( get_option( 'options_title' ) );
$button_text = esc_html( get_option( 'options_button_text' ) );
$button_url  = esc_url( get_option( 'options_button_url' ) );

if ( $title && $button_text && $button_url ) {
    echo '<div class="call-to-action"><div class="wrap"><p>' . $title . '</p><p><a href="' . $button_url . '" class="button">' . $button_text . '</a></p></div></div>';
}

Term Metadata

אם הוספתם שדה בשם "כותרת משנית" לקטגוריות, ACF שומר נתונים אלו בטבלת wp_termmeta (החל מ-ACF 5.5 ו-WordPress 4.4+). ניתן לשלוף באמצעות get_term_meta():

if ( ! is_category() ) {
    return;
}

$category = get_queried_object();
$subtitle = esc_html( get_term_meta( $category->term_id, 'my_subtitle', true ) );

if ( $subtitle ) {
    echo '<p class="subtitle">' . $subtitle . '</p>';
}

בגרסאות ACF לפני 5.5, term metadata נשמר בטבלת wp_options בפורמט [taxonomy]_[term_id]_[field_name]. החל מ-ACF 5.5, נתוני terms נשמרים בטבלת wp_termmeta, ונגישים דרך פונקציית וורדפרס הסטנדרטית get_term_meta().

שאלות נפוצות

שאלות נפוצות על שימוש ב-ACF ללא תלות ב-frontend:

האם get_post_meta מהיר יותר מ-get_field ב-ACF?
כן. get_post_meta() שולף את הערך הגולמי ישירות מ-cache של מסד הנתונים, בעוד get_field() מריץ לוגיקת עיצוב נוספת ועשוי להפעיל שאילתות נוספות למסד הנתונים בהתאם לסוג השדה. עבור שדות תמונה ושדות repeater, ההבדל הוא המשמעותי ביותר.
מה קורה לאתר אם ACF מושבת?
אם התבניות שלכם משתמשות ב-get_field() ו-ACF מושבת, הגולשים יראו שגיאה קריטית ודף ריק. אם תשתמשו ב-get_post_meta() במקום, האתר ממשיך לעבוד כרגיל כי הנתונים עדיין קיימים במסד הנתונים ופונקציות הליבה של וורדפרס תמיד זמינות.
כיצד ACF שומר נתוני repeater field במסד הנתונים?
ACF שומר נתוני repeater field כשורות בודדות ב-wp_postmeta. מפתח ה-repeater הראשי שומר את מספר הפריטים. כל תת-שדה נשמר בתבנית [repeater_name]_[index]_[sub_field_name]. למשל, repeater בשם my_videos עם 3 פריטים שומר את הספירה כ-my_videos = 3 וכל כותרת כ-my_videos_0_title, my_videos_1_title וכו'.
היכן ACF שומר את נתוני Options Page?
ACF שומר נתוני Options Page בטבלת wp_options עם שם השדה שלכם בתחילית options_. למשל, שדה בשם title נשמר כ-options_title. שלפו אותו באמצעות get_option('options_title') במקום get_field('title', 'option').
האם עטיפת פונקציות ACF ב-function_exists פותרת את בעיית התלות?
חלקית. עטיפת קריאות ACF ב-function_exists('get_field') מונעת את השגיאה הקריטית אם ACF מושבת, אבל כל נתוני השדות המותאמים פשוט לא יופיעו ב-frontend. שימוש ב-get_post_meta() במקום מבטיח שהנתונים תמיד מוצגים ללא קשר לכך אם ACF פעיל.

סיכום

שימוש בפונקציות הליבה של וורדפרס כמו get_post_meta(), get_option(), ו-get_term_meta() במקום get_field() של ACF מבטל את התלות ב-frontend בתוסף, מצמצם שאילתות למסד הנתונים, ומבטיח שהאתר שלכם ממשיך להציג תוכן גם אם ACF מושבת.

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

הנה פוסטים קשורים:

דיון ותגובות
9 תגובות  ]
  • רמי 5 יולי 2016, 14:15

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

    https://GenerateWP.com/generator/

  • אבי 22 אוגוסט 2018, 15:42

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

    <?php echo wpautop(get_post_meta( get_the_ID(), 'repeater_' . $i . '_review', true )); ?>

    ורק אז זה יוסיף את המרווחים הנכונים. מקווה שזה יעזור למישהו…

  • אבי 7 אוקטובר 2018, 17:19

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

    לצערי נאלצתי להמיר קוד שלם לדרך המובנית של התוסף… אם יש פתרון אשמח לשמוע 🙂

  • עמנואל אמירוב 23 נובמבר 2018, 15:52

    קצת הסתבכתי בזה (אני לא מתכנת).

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

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

השאירו תגובה

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

Savvy WordPress Development official logo