בפוסט הזה אראה איך ליצור כפתור בעורך TinyMCE שמאפשר למשתמש ליצור shortcode, ואיך התוסף Shortcake מאפשר גם לערוך אותו.
אחד הפרוייקטים שלי הוא עבור עמותה המקיימת פעילויות עבור חבריה. כשהפעילות כרוכה בתשלום – למשל טיול – אחת מדרכי התשלום היא באמצעות אתר פלא-פיי. כדי לחסוך לנרשמים את הצורך למלא את סכום התשלום בעצמם, יצרו מתכנתי האתר שקדמו לי, טופס שמופיע בפוסט של ההרשמה לפעילות. בטופס הזה, הנרשמים בוחרים את הסכום לתשלום (עפ”י היותם חברי העמותה או לא), ולוחצים על כפתור התשלום. כך הם מועברים לאתר פלא-פיי, יחד עם הסכום לתשלום אותו בחרו.
איך מוכנס הטופס לפוסט? טוב ששאלתם.
אפשרות אחת היא שמנהל האתר יעשה זאת. אבל מה יעשה מנהל אתר שאין לו מושג בקוד? הוא לא ישוש להכניס את הטופס בעצמו (גם אם מדובר רק ב-copy + paste מפוסט אחר), כי דברים עלולים להשבר בקלות (מספיק שתגית אחת לא נסגרת כראוי, וכל הפוסט מתחרבש). ואם, בנוסף, מדובר על שינוי שדות בטופס (למשל אם המחיר השתנה) אז על אחת כמה וכמה.
לכן לפעמים הוא יעדיף אפשרות שנייה: לבקש ממתכנת לעשות זאת. גם זו לא כזאת אפשרות נפלאה, הן מצד מנהל האתר, שנהיה תלוי באדם נוסף; והן מצד המתכנת, שההתעסקות הזאת היא מיותרת מבחינתו.
וזה עוד בלי להתייחס לעובדה שקוד בתוך פוסט מוּעַד לפורענות – וורדפרס אוהבת למחוק קוד HTML מפוסטים…

אז אף אחת משתי האפשרויות אינה מלהיבה. צריך למצוא אפשרות שתתן למנהל האתר להיות עצמאי, בלי שפעולותיו תסכנה את הפוסט.
הפתרון – shortcode.
במקום להכניס לכל פוסט את קוד ה-HTML של הטופס, נכניס shortcode שיתורגם לקוד. כך ההעתקה וההדבקה הם פחות מסוכנים – גם מפני שזה קצר יותר, וגם מפני שאפילו אם ההעתקה משתבשת, זה לא יהרוס את ה-HTML. חוץ מזה שזה פותר את בעיית מחיקת הקודים מהפוסטים שוורדפרס כה חובבת.
חשבתי, ועשיתי.
יצרתי shortcode בשם pelepay_form שמקבל מאפיינים של סכומים לתשלום, מלל לכל סכום, ומספר תשלומים (נשמר בשדה נסתר). כעת מספיק שמתכנת ייצור את ה-shortcode פעם אחת, ובפעמים הבאות, מנהל האתר יעתיק אותו לפוסט הרלוונטי. אפילו שינוי הסכומים לתשלום הוא קל יותר, כי אין הרבה קוד HTML שעוטף את המקומות שצריך לשנות.
אבל עדיין לא הייתי מרוצה. אמנם הצלחתי לחסוך מעורך האתר מגע עם קוד אמתי, אבל עדיין, הוא צריך לגעת ב-shortcode ולשנות בו ערכים. אפשרי, אבל ממש לא אידיאלי.
הרעיון הבא היה – ממשק גרפי. למה לא ליצור חלונית עם שדות טקסט שמנהל האתר ימלא, וזה ייצור את ה-shortcode? כך הוא אף פעם לא יצטרך לגעת בשום קוד, ואפילו לא להעתיק ולהדביק אותו.
ואיך יופעל הממשק הגרפי? ע”י כפתור בעורך הטקסט שיוגדר במיוחד לשם כך:
איך מפתחים כפתור כזה? לא ידעתי.
אז חיפשתי מדריך (tutorial) שיסביר לי איך לעשות את זה. מאחר שלא חסרים מדריכים בנושא, הייתי זקוקה לקריטריון שיעזור לי להחליט מיהו tutorial טוב. הימים היו ימי וורדפרס 3.9, שבה השתנה הייצור של כפתורי ה-TinyMCE: במקום תמונות, עברו לשימוש ב- font icon. החלטתי שרק מדריך שיסביר איך ליצור כפתור בדרך החדשה, עם font-icon, יתקבל.
כך הגעתי למאמר מפורט ויסודי ביותר על אופן הוספת כפתורים ושאר מרעין בישין ל-TinyMCE בוורדפרס (לזכותו ייאמר שהוא הכיל הסברים הן על הדרך הישנה והן על הדרך החדשה!).
מאחר שכל הקוד נמצא ב-tutorial, אכתוב כאן את השלבים הנצרכים כדי לבנות כזו חלונית, ואקשר לדוגמאות הקוד של ה-tutorial:
- יצירת ה-Shortcode
- הוספת הכפתור לעורך
- הגדרת פונקציה שיושבת על
admin_head
ומקשרת שתי פונקציות לשני פילטרים:mce_external_plugins
,mce_buttons
. הפונקציה הראשונה, מגדירה את הנתיב של קובץ ה-JS כפלגאין של TinyMCE; הפונקציה השניה מוסיפה את הכפתור למערך הכפתורים של TinyMCE - יצירת אייקון – המדריך מסביר איך להוסיף איקון מסדרת ה-Dashicons, שאינו מופיע בעורך. זה כולל מתן Class לאייקון בקובץ ה-JS, יצירת קובץ CSS והגדרת ה-Class שנתנו כך שיראה את האיקון המבוקש, והכללה של קובץ ה-CSS (
enqueue
). - יצירת החלונית – כתיבת קוד בקובץ ה-JS (הקובץ שהוגדר בשלב 2.1) הפותח חלונית כשמקליקים על הכפתור שיצרנו. האפשרות הכי פשוטה היא חלונית עם שדה טקסט, וכפתורי אישור וביטול. יש גם אפשרות לפקדים מתקדמים יותר.
- תרגום – שמות ה-label-ים בחלונית צריכים להיות בעברית, כדי להקל על המשתמש. הפתעה נעימה הייתה שהמדריך התייחס לנושא התרגום (דבר שנזנח פעמים רבות ב-tutorial-ים הנכתבים ע”י דוברי אנגלית).
שימוש ב-load_textdomain
אוload_plugin_textdomain
כמובן לא רלוונטי, מפני שהם נועדו לתרגום ב-PHP. אבל גםwp_localize_script
לא יועיל, מפני ש-TinyMCE לא יודע להתייחס לזה. הפתרון הוא הפילטרmce_external_languages
, שהפונקציה המחוברת אליו מוסיפה אלמנט נוסף לטבלת ה-$locals
, המציין קובץ תרגום נוסף בשםtranslations.php
. צריך ליצור את הקובץ הזה ולהכניס בו את התרגומים לפי ההסבר במדריך, ולאחר מכן, להוסיף את הקריאה לתרגומים בקובץ ה-JS, ע”י שימוש ב-editor.getLang
.
- הגדרת פונקציה שיושבת על
וזו התוצאה:
בעיקרון, לפי חוק הפרדת הרשויות – שלפיו מה שקשור לעיצוב שייך בתבנית ומה שקשור בפונקציונליות שייך בתוסף – את כל הקוד בפוסט הזה כדאי להכניס לתוסף ייעודי. אם, משום מה, לא בא לכם (אבל למה? זה קלי קלות ליצור תוסף, וזה עוד יותר קלי קלות עם התוסף שיוצר תוספים. מי שראה את הסרט Inception יבין את שם התוסף 🙂 ), אז את הקוד אפשר להכניס ל-functions.php
של התבנית, או, עדיף, לקובץ נפרד שנקרא מתוך functions.php ע”י require_once
. כשיש מקומות שבהם צריך לכתוב את הקוד בקבצים אחרים, זה מפורט במדויק תוך כדי ההדרכה.
**
לתקופה מסויימת, הכל היה נפלא וזרם על מי מנוחות.
ברם אולם, אחרי זמן מה, עלה עלה הצורך לשנות משהו במלל. אמנם את הסכומים קל היה לשנות ב-shortcode עצמו, אבל עריכה של עברית (הטקסט שאמור להופיע בטופס) משולבת באנגלית (שמות המאפיינים של ה-shortcode) היא כבר יותר מאתגרת.
הפתרון – יכולת לערוך את ה-shortcode בממשק גרפי.
לשמחתי, שמעתי על תוסף בשם Shortcake, שזו עיקר מעלתו: לאפשר עריכת shortcode-ים. ובונוס: במקום לראות בפוסט את הסוגריים המרובעים, אפשר לראות את התוצר עצמו:
כדי לאפשר עריכה כזאת, צריך “לרשום” את ה-shortcode שלנו באופן כזה שהתוסף ייצר חלונית עריכה, שבה יהיו אותם שדות שיש בחלונית היצירה, רק שהערכים שכבר הוכנסו ב-shortcode יופיעו בהם. ה”רישום” הוא ממש פשוט: יש ליצור פונקציה שיושבת על על hook
של register_shortcode_ui
, וממפה את השדות והשמות שלהם. הקוד הזה דומה להפליא לקוד שכתבנו בקובץ ה-JS כשיצרנו את הכפתור, רק שהקוד ההוא היה ב-JS, והקוד הנוכחי הוא ב-PHP.
זה ה-JS (חלק מתוך הקוד שיוצר את החלונית שהכפתור מפעיל):
... body: [ { type: 'textbox', name: 'price_list', label: editor.getLang('pelepay_tc_button.price_list') }, { type: 'textbox', name: 'price_text', label: editor.getLang('pelepay_tc_button.price_text') }, { type: 'textbox', name: 'payment_for', label: editor.getLang('pelepay_tc_button.payment_for') }, { type: 'textbox', name: 'payments', label: editor.getLang('pelepay_tc_button.payments_text') } ], ...
וזה ה-PHP (מתוך הקוד ש”רושם” את ה-shortcode שלנו ב-shortcake):
... 'attrs' => array ( array ( 'label' => esc_html__( 'Comma separated price list', $this->plugin_name ), 'attr' => 'price_list', 'type' => 'text', ), array ( 'label' => esc_html__( 'Comma separated price text list', $this->plugin_name ), 'attr' => 'price_text', 'type' => 'text', ), array ( 'label' => esc_html__( 'Payment for...', $this->plugin_name ), 'attr' => 'payment_for', 'type' => 'text', ), array ( 'label' => esc_html__( 'Max number of payments', $this->plugin_name ), 'attr' => 'payments', 'type' => 'text', ), ), ...
כמו שאתם רואים, הקוד מאד פשוט. במקרה שלי זה כך גם מפני שיש לי רק שדות טקסט בחלונית. עקרונית התוסף מאפשר הרבה יותר סוגים של שדות. כמו-כן, אני השתמשתי רק ב-3 מאפיינים לכל שדה: type
, attr
, label
. יש עוד כמה מאפיינים שמוסברים בקוד הזה בגיטהאב, ובאחד מהם עוד אשתמש בהמשך הפוסט.
וזה כל מה שצריך לעשות – ליצור הפונקציה הזאת (שכאמור היא גרסת PHP לפונקציה שבונה את החלון מהכפתור), ולשייך אותה ל-hook.
אך זה אינו סוף הסיפור. כמו בסיפורים רבים, גם כאן יש טוויסט יהודי.
שמחה וטובת לב הודעתי לעורך האתר שיש באפשרותו לערוך את שדות הטופס. בתגובה קיבלתי את הדואל הבא:
ניסיתי להוסיף את זה לשורת “בעבור”: טיול חוה”מ פסח תשע”ושמרתי, ו…. לא נשמר.
htmlspecialchars
לשימוש ב-PHP בעת תרגום ה-shortcode. כאמור, כל זה נשכח ממני בעת ההתאמה לעריכה.array ( 'label' => esc_html__( 'Payment for...', $this->plugin_name ), 'attr' => 'payment_for', 'type' => 'text', 'encode' => true, ),
htmlspecialchars
כל שדות הטקסט בפונקציית ה-callback של ה-shortcode, זה יספיק, אך התברר שלא. גוגל שלח אותי לקרוא את הקוד שמממש את ה-shortcake, וראיתי איך הוא מתמודד שם כשהמאפיין encode דלוק: הוא משתמש ב-rawurldecode
. הנוסחה המנצחת היא קודם rawurldecode
(קודם להמיר את ה-decode בחזרה לתווים רגילים) ואח”כhtmlspecialchars
(שממירה תווים מיוחדים לישויות HTML-יות):htmlspecialchars(rawurldecode ($atts['payment_for']));
ועכשיו נראה שבא לציון גואל 🙂 .
מבחינה מסויימת, כל עניין בניית הכפתור והחלונית הם קצת מיותרים כשישנו התוסף הזה, כי בעצם, התוסף מאפשר להכניס shortcode בלי להצטרך להגדיר כפתור בעורך וליצור את החלונית הנפתחת בעצמנו. הוא משתמש בחלון הוספת המדיה, ומוסיף בתפריט אפשרות נוספת, בשם “הכנס אלמנט לפוסט”, שלחיצה עליו מראה את כל ה-shortcode-ים הרשומים באתר בצורת ריבועים עם איקון עליהם (“הרשומים” פירושו, אלה שנכתבה עבורם פונקציה כדלעיל), ואז לחיצה על הריבוע הרלוונטי פותחת חלון שבו ניתן להכניס ערכים למאפיינים של ה-shortcode.
אבל אני בכל זאת שמחה על הכפתור – בעיניי זה לא כ”כ אינטואיטיבי להשתמש בהוספת המדיה לשם יצירת שורטקוד.
אם תוסף ה-shortcake מעניין אתכם, יש דיבורים על הכנסתו ל-core. אפשר לעקוב אחרי הדיון כאן, כרגע הכיוון הוא בגרסה 4.6.
לא היו בעיות עם גרשיים אם היו משתמשים בגרשיים אמתיים (״) ולא בסימן הלועזי (“).
מה, המשתמש אשם? 😉
אבל איך עושים גרשיים אמתיים? הגרשיים שיש בעברית הם לא נכונים?
המשתמש לא אשם והמתכנת צריך לחשוב על כל המצבים.
לגרשיים יש תו מיוחד ביוניקוד (U+05F4) אבל כיוון שהוא לא הופיע בעבר על מקלדות רגילות רגילים להשתמש במקומו במירכאות לועזיות (u+0022).
לפי הערך בוויקיפדיה (שלא לגמרי מדויק) הסימן הוסף למקלדת בווינדוס 8 כחלק מתקן המקלדת החדש.
אם מעניין אותך תוכלי למצוא עוד מידע בוויקי של עמותת המקור.
איזה כיף שהתגובות שלך כאלה מלמדות. אתה יודע, רק המתגובות שלך אתה יכול לכתוב פוסטים מעניינים!
לבושתי, לא שמתי לב עד עכשיו שיש הבדל בין גרשיים למרכאות. מגניב.
ותודה שוב על הגרשיים האלה.
הם הצילו אותי בפוטושופ
(הגרשיים הרגילים של המקלדת יושרו כל הזמן לצד הלא נכון…)
בבקשה, זה כבר נושא נרחב אחר של כיווניות תווים שלא אכנס אליו כרגע.
מחכה לפוסט 😉