מדריך | כתיבת סקריפט צד לקוח עבור אתר NodeBB - שימוש בhooks
-
שלום לכולם!
זה המדריך הראשון שאני כותב בתכנות, מקווה שיצא מספיק ברור ולא מידי "נמרח" ומתעכב על דברים שפשוטים מאיליהם לכל מתכנת ממוצע...
הערות והארות יתקבלו בשמחה - עדיף בנושא נפרד...
לפני שמתחילים - הבהרה קטנה: המדריך כולו מדבר כרגע אך ורק על הוקי פעולה, בצד לקוח, ולא על הוקים בצד שרת, שמשמשים בכתיבת תוספים, וזאת מהסיבה הפשוטה - שעדיין לא הבנתי איך זה עובד בצד שרת...
אם ניסיתם פעם לכתוב סקריפט עבור אתר NodeBB (לדוגמה הפורום הזה...), ודאי נתקלתם בבעיה - איך להאזין לשינויים בדף.
כלומר אם כתבתם קוד מסוים שאמור לשנות משהו, אפילו שינוי קוסמטי בתיבה של כתיבת הפוסטים, או בתוך חלונית ההתראות/הצ'אטים, הקוד לא ישפיע - כיוון שהאלמנט בעצם לא קיים בזמן טעינת הדף (שאז הסקריפט רץ), ובשונה ממדיה ויקי לדוגמה - הדף לא מתרענן בעת ביצוע פעולות (כמו יצירת פוסט, עריכה שלו, וכן הלאה), וכתובתו לא משתנית.
הסיבה לכך היא שנודביבי משתמשים בשיטה שנקראת הוקים (hook), שזה אומר שהנודביבי "פולט אירועים" לסקופ של window, להם ניתן להאזין בקלות ולבצע פעולות שונות כאשר הם מתבצעים.הנה לדוגמה קוד שמאזין ל
action:composer.topics.post
(שליחה של פוסט חדש בנושא קיים), וכאשר הוא מתבצע, מקפיצים הודעת אישור, ומדפיסים לקונסול את המידע שהוא מחזיר (לדוגמה תוכן הפוסט, מזהה נושא, וכן הלאה).$(window).on("action:composer.posts.reply", function (event, data) { app.alertSuccess("hook 'action:composer.posts.reply' run."); //הודעה console.log(data); //כאן מדפיסים את המידע המפורט יותר שמתקבל מההוק, פירוט בהמשך. });
ניתן כמובן להדפיס גם את התוכן של ה-event.
וכמובן שניתן גם לבצע פעולות שונות על סמך המידע שמתקבל מההוק;
לא לכל פעולה יש הוק נפרד.
לדוגמה עבור מערכת המוניטין, יש רק הוק אחד -action:post.toggleVote
, שמתבצע בכל שינוי בלייקים - מתן/הסרת לייק או מתן/הסרת דיסלייק.
מה קורה אם רוצים לבצע פעולה מסוימת רק במקרה מסוים? כגון רק אם נתנו דיסלייק - להקפיץ הודעה "שימו לב, מתן דיסלייקים ללא הצדקה נוגד את חוקי הפורום ועלול להביא להרחקה"?
בשביל זה צריך לקבל את המידע מההוק, ולהכניס משפט תנאי שיבדוק מה התבצע בדיוק;
הנה דוגמה:$(window).on("action:post.toggleVote", (ev, hookData) => { // כאן נכנס התנאי שבודקים if (hookData.delta === -1 && hookData.unvote === false) { //כפתור 1 = לייק, מצב חדש: כפתור פעיל alert("התווסף דיסלייק"); //הודעה מובנית של הדפדפן - אפשר כמובן להפעיל כל קוד/פונקציה שרוצים. } });
הקוד הזה, לדוגמה, מקפיץ alert פשוט של הדפדפן, כאשר מתרחש אירוע של toggleVote, כאשר ערך ה"delta" - כלומר באיזה כפתור התבצע האירוע, הוא 1-, כלומר לחצן הדיסלייק, והמצב שאליו האירוע הביא את הכפתור, זה false, שזה אומר מצב פעיל. (ההיגיון אומר שזה אמור להיות להיפך, אבל ככה זה עובד...)
וכך ניתן לבודד בדיוק את האירוע שהתרחש באמצעות משפט תנאי פשוט:hookData.delta === 1 && hookData.unvote === false //נתינת לייק hookData.delta === 1 && hookData.unvote === true //הסרת לייק hookData.delta === -1 && hookData.unvote === false //נתינת דיסלייק hookData.delta === -1 && hookData.unvote === true //הסרת דיסלייק
התיעוד שיש - הוא חלקי ביותר, ישנה רק רשימה אוטומטית שלא כוללת כמובן שום הסבר על השימוש בכל הוק, מכילה כפילויות רבות, ולא כוללת למשל הוקים מפורטים עבור המלחין - שזה בעצם מה שיוצר את הממשק שבו כותבים את הפוסטים, כיוון שזה נוצר על ידי תוסף ולא בבסיס הקוד.
בעז"ה בפוסט הבא:
- רשימה של הוקים שימושיים שליקטתי, כולל הוקים מפורטים יותר עבור ה"מלחין" (שזה בעצם מה שיוצר את התיבה שבה כותבים את הפוסטים בפורום), שכמו שכתבתי - אין עליו הוקים ברשימה האוטומטית.
- כלי קטן שכתבתי, לבדיקה בקלות של הוק - מתי הוא מתבצע ואיזה מידע הוא מחזיר.
-
שוב שלום
בפוסט הקודם פירטתי על הוקי פעולה, ויצא מדבריי הרושם שהוק פעולה של צד לקוח חייב להתחיל ב":action
", אבל ישנם גם הוקי פעולה שמתחילים ב":event
" ומאזינים להם בצורה שונה:socket.on('event:new_notification', function (data) { console.log(data); });
קוד זה לדוגמה בודק את ההוק שנוצר בעת שליחת פוסט חדש לנושא קיים; שימו לב שמאזינים ל'socket' ולא ל-window.
Hooks NodeBB Tools
כתבתי סקריפט קטן, שמאפשר בדיקה קלה של הוקים.
אם לדוגמה מוצאים בקוד המקור הוק, אבל לא יודעים בבירור למה הוא משמש, או איזה מידע הוא מחזיר, ניתן להכניס את שם ההוק לסקריפט, ולבצע את הפעולה (למשל עריכת פוסט), וברגע שיופעל האירוע של ההוק - יופץ alert שמודיע איזה הוק הופעל (ניתן לבדוק כמה הוקים בו זמנית), והמידע שמוחזר מההוק יודפס בקונסול.
כאן פירטתי את הוראות ההתקנה.
לאחר ההתקנה פשוט לוחצים על קונטרול + Q, ומייד תוקפץ תיבת קלט להכנסת שם ההוק.
כברירת מחדל הקוד פועל רק באתר תחומים ומתמחים טופ, אבל ניתן כמובן להתאים אישית את רשימת האתרים על פי שורות 8-9 בסקריפט. -
בפוסטים הקודמים כתבתי רק על האזנה לאירועים של NodeBB בצד הלקוח.
אלא שניתן גם ליזום אירועים, וכך ניתן לבצע פעולות בממשק בצורה נקיה, ללא צורך בדימוי לחיצות ושאר שטיקים מכוערים...
לדוגמה אם אני רוצה לפתוח נושא חדש (זה רק דוגמה, ספציפית בזה יש אתapp.newTopic
), אני לא צריך לדמות לחיצה על כפתור פתח נושא, ואז לדמות לחיצה על בורר הקטגוריות, וכן הלאה...
אני יכול פשוט לקרוא לאירועaction:composer.topic.new
(מאיפה יש לי אותו? מהתיעוד הרשמי) עם הפרמטרים הנכונים,ואיך אני יידע איזה פרמטרים? פשוט מאזינים להוק הרלוונטי ומפעילים אותו בממשק, ורואים בקונסולה איזה פרמטרים הועברו אליו... אפשר גם להיעזר בסקריפט שהבאתי בפוסט הקודם
לדוגמה כדי להאזין להוק של יצירת נושא:$(window).on('action:composer.topic.new', (event, data) => { console.log(data); });
אם תאזינו כך להוק של פתיחת נושא, תוכלו לראות שהוא מקבל אובייקט שמכיל
cid
ומערך שלtags
, שבמקרה הזה הם ריקים:{ "cid": 0, "tags": [] }
וממילא ברגע שנקרא להוק בצורה הזאת:
$(window).trigger('action:composer.topic.new', { cid: "9", tags: [ 'test', 'test2' ] });
נראה שנפתח מייד חלון כתיבת נושא חדש, כאשר ב"קטגוריה" כבר נבחרה קטגוריה מספר 9 - בניה ושיפוצים, ובמקום המיועד כבר הוכנסו התגיות
test
וtest2
:
ותן לחכם ויחכם עוד...