לאחרונה התבקשתי ליצור תוסף (אם מעניין אתכם לדעת, אז מה שהוא עושה זה מציג ב-my את כל הפעילויות ומשאבים שנוספו בקורסים בהם הם משתמשים בתפקיד שיצרנו: מורה משתף, אבל לא אכנס ללוגיקה של התוסף). זו לא הפעם הראשונה שאני יוצרת תוסף אבל אני לא יוצרת אותם בתדירות מספיק גבוהה כדי לזכור איך לעשות את זה כל פעם. לכן החלטתי עכשיו לתעד את החלקים החשובים בתהליך כדי לחסוך לי כמה דקות בפעם הבאה.
בפוסט הזה אלא אתמקד בשני דברים כללים שאני תמיד צריכה: בניית תוסף, ושימוש ב-mustache.
בניית תוסף בסיסי
מערכת המוודל שלנו היא בגרסה 3.3, והתוסף הזה מתאים לגרסה זו. אני לא יודעת מה יהיה מצבו בגרסאות קודמות או מתקדמות יותר.
בבניית התוסף הסתמכתי על התיעוד של מוודל, אבל לא הייתי צריכה את כל הקוד משם ולכן העדפתי להשתמש בתבנית מוכנה של תוסף, ולמחוק ממנה מה שלא מתאים לי.
לקחתי תבנית מוכנה, והסרתי ממנה את הקבצים הבאים:
.travis.yml
composer.json
edit_form.php
settings.php
גם ב-block_newblock.php
מחקתי קוד. חלק מחקתי כדי שההסרות של הקבצים הנ”ל לא תשפענה על הקוד, וחלק כי לא הייתי צריכה את הקוד עצמו:
- ב-
get_content
מחקתי הכל מלבד השורות שממלאות את$this->content
כדי שאוכל להחזיר אותו.function get_content() { global $CFG, $OUTPUT, $DB, $USER; if ($this->content !== null) { return $this->content; } if (empty($this->instance)) { $this->content = ''; return $this->content; } $renderer = $this->page->get_renderer('block_lifeneighbor'); $this->content = new stdClass(); $this->content->text = ''; $this->content->footer = ''; return $this->content; }
- בפונקציה
has_config
הגדרתי שיחזירfalse
כי אין קובץsettings.php
. - גם את הפונקציה
instance_allow_multiple
הגדרתי שתחזירfalse
. משבצת אחת מספיקה. - את הפונקציה
applicable_formats
שיניתי מפני שרציתי שהמשבצת תופיע רק בדף “העדכונים שלי”. פירוט בפיסקה הבאה. - את הפונקציה
cron
מחקתי.
כדי שמשבצת תופיע בדף העדכונים שלי, ורק שם
צריך להגדיר בשני מקומות:
המקום הראשון הוא ב-db/access.php
של המשבצת יש מערך של capabilities. הפריט הראשון אומר לו להראות את המשבצת בדף ה-my:
$capabilities = array( 'block/lifeneighbor:myaddinstance' => array( 'captype' => 'write', 'contextlevel' => CONTEXT_SYSTEM, 'archetypes' => array( 'manager' => CAP_ALLOW ), 'clonepermissionsfrom' => 'moodle/my:manageblocks' ), 'block/lifeneighbor:addinstance' => array( 'riskbitmask' => RISK_SPAM | RISK_XSS, 'captype' => 'write', 'contextlevel' => CONTEXT_BLOCK, 'archetypes' => array( ), 'clonepermissionsfrom' => 'moodle/site:manageblocks' ), );
(הפריט השני נועד כדי לא לקבל שגיאות במסכים אחרים, שבהם איננו רוצים שהמשבצת תופיע).
המקום השני הוא הפונקציהapplicable_formats
. כך צריך להגדירה:
public function applicable_formats() { return array('my' => true ); }
הצגת התוכן באמצעות Mustache-ים
בגרסאות האחרונות של מוודל, התחילו להכתוב HTML בתבניות mustache. אפשר לקרוא על mustache כאן, על התחביר שלו כאן, ועל שילובו ב-Moodle – כאן. יצא לי להשתמש ב-mustache בתבנית שבניתי בשנה שעברה (ושאני עדיין מקווה לכתוב קצת עליה בבלוג) כך שלא באתי כלוח חלק. חוץ מזה, כמו בתבנית, אני לא אוהבת להתחיל מאפס אלא לקחת משהו דומה שכבר קיים, ולהתאים אותו לצרכיי.
- יצירת קובץ ה-mustache:
הקוד שרציתי לייצר היה דומה מאוד לזה שיוצרת המשבצתmyoverview
, אז לקחתי ממנה את הקובץcourses-view-course-item.mustache
ושמתי במשבצת שלי תחת תיקייתtemplates
. - הקריאה לקובץ ה-mustache:
צריכה להיעשות מתוךrenderer
. יצרתי תיקייתclasses
ובתוכה תיקייתoutput
. בתוכה יצרתי קלאס בשםrenderer
ויצרתי פונקציה בשםrender_main
. הפונקציה קוראת לפונקציהrender_from_template
ממחלקת הבסיס, מעבירה לה כפרמטר ראשון את שם קובץ ה-mustache
, ובפרמטר השני את המידע שאותו יציג קובץ ה-mustache
(אני העברתי קריאה לפונקציה שתיצור את זה)./** * Return the main content for the block overview. * * @return string HTML string */ public function render_main() { return $this->render_from_template('block_lifeneighbor/courses-view-course-item', $this->export_for_template($this)); }
- בפונקציה
get_content
שיניתי את מה שמשימים ל-$content->text
. יצרתי אוביקט שקורא ל-renderer והעברתי ל-$content->text
את מה שמחזירה הפונקציה:$renderer = $this->page->get_renderer('block_lifeneighbor'); $this->content->text = $renderer->render_main();
מה מציג ה-mustache
יש סוגים שונים של data שהייתי צריכה להציג בתוסף הזה, וכל אחד מהם אתגר אותי בצורה שונה. אפרט כאן את הסוגים השונים ואת דרכי הצגתם. מטבע הדברים יש עוד סוגי data שאפשר להציג עם mustache, אבל הפוסט הזה מתעד רק את מה שאני חוויתי.
אנחנו רוצים להראות מערך של קורסים. המערך מכיל אוביקטים שכל אחד מהם הוא קורס.
קודם ניצור את המעטפת של ה-HTML שיציג את המערך
- ניצור את המערך בפונקציה שהגדרנו (ושאת שמה שלחנו כפרמטר ל-
render_from_template
)$output[$i++]['coursename'] = $recent_activity->fullname;
- נחזיר את המערך ונקרא לו
coursesview
:return [ 'coursesview' => $output ];
- בקובץ ה-mustache נעטוף את כל ה-HTML המיוצר בתגית שבודקת אם קיים אוביקט
coursesview
:{{#coursesview}} {{/coursesview}}
כעת ניצוק לתוך תגיות ה-HTML שדות מהאוביקטים שממלאים את המערך
- בתוך העטיפה הנ”ל ניצור את ה-HTML, שבו למשל בכותרת נקרא לפריט ה-
fullname
שמילאנו בו{{#coursesview}} <h4><a href="{{viewurl}}" class="">{{coursename}}</a></h4> {{/coursesview}}
אם מערך מכיל טיפוס פשוט כמו int או מחרוזת, ולא אוביקט עם שדות
למשל מערך כזה:
"coursemodules": Array { [0] => "מטלה ב'", [1] => "מטלה א'"}
אז כדי להציג את התוכן של כל איבר נשתמש בנקודה:
{{#coursemodules}} <a href="{{moduleurl}}"> {{.}} </a> {{/coursemodules}}
אם השדה מכיל תגית HTML
אם נקרא לו כרגיל, עם שני סוגריים מסולסלים לפניו ואחריו, ה-HTML יעבור encoding ויוצג כטקסט רגיל ולא כקוד. כדי להציג את זה כקוד, צריך לעטוף את השדה ב-3 סוגריים מסולסלים:
{{{icon}}}
וזהו.
***
מעניין אותי באיזו דרך אתם בונים תוספים, מה החוויות שלכם משילוב mustache, ובכלל, כל מה שיש לכם להוסיף או להעיר על הפוסט יתקבל בברכה.
