באחד הפרוייקטים שלנו היינו זקוקים לוידג’ט שמציג סרטונים. יש כמובן רבים כאלה, ובחרנו אחד מתוכם. הוא התאים מאד לכל צרכינו, מלבד העובדה שהוא נתן למשתמש (מנהל האתר) יותר מדי אופציות בניהול של הוידג’ט. אנחנו רצינו לתת למשתמש למלא רק 3 שדות:
- כותרת לסרטון
- כתובת הסרטון
- סוג שירות הוידיאו (יוטיוב, וימיאו, וכו’)
כמובן שלא רצינו לגעת בוידג’ט עצמו (כדי שנוכל להמשיך לעדכן אותו בעתיד), לכן חיפשנו דרך להשפיע על הוידג’ט מבחוץ, כלומר מתוך התבנית שלנו. בעצם ההשפעה שלנו היתה צריכה להיות בשני מישורים: הראשון – התצוגה. לא רצינו שהמשתמש יראה אופציות שאיננו רוצים שהוא ישנה. השני – בערכי האופציות. רצינו שאותן אופציות שלא נראות למשתמש, תקבלנה ערכים שאנחנו קבענו מראש.
נתחיל מהשני: התברר שניתן להשפיע על ערכי האופציות של הוידג’ט, באמצעות hook ששמו widget_update_callback
. הה-hook הזה נקרא, למרבה ההפתעה, בזמן שמופעלת פונקציית ה-save של הוידג’ט (האמת היא, שלא כל וידג’ט בנוי כך שה-hook הזה נקרא בזמן ה-update שלו. אבל לשמחתנו הודיג’ט שהשתמשנו בו היה בנוי כך שהוא כן). הפונקציה מקבלת ארבעה פרמטרים (אין על זה ערך ב-codex, אבל אפשר לחפש בקוד ה-core את ה-hook הזה, ושם רואים את ארבעת הפרמטרים): $instance, $new_instance, $old_instance, $widget
. בתוך הפונקציה אפשר להשתמש ב-$widget->id_base
כדי לוודא שאנחנו בוידג’ט הנכון, ואח”כ להשתמש ב-$instance
שהוא מערך של כל השדות שיש בטופס. חשוב לזכור שלא משנה במה אנחנו נוגעים, גם אם לא נגענו ב-$instance
בכלל, להחזיר את $instance
.
למשל כך:
/* Make the vidoe widget always have autoplay turned off (because their default is on, and we dont want that) */ add_filter ( 'widget_update_callback', 'mop_change_widget_settings', 10, 4 ); /** * Change the default behavior of the video widget and category widget * video widget to NOT autoplay, and set height and weight * category to always show excerpt and thumbnail * @param array $instance * @return int */ function mop_change_widget_settings ( $instance, $new_instance, $old_instance, $widget ) { /* * ******************* Video Widget ******************* */ // when we're in video widget, set the autoplay to No, in order to override the default settings of the widget if ( $widget -> id_base == 'videosidebar' ) { if ( isset ( $instance[ 'v_autoplay2' ] ) ) { $instance[ 'v_autoplay2' ] = 0; } /* also automatically set the height and width, so that html errors don't emerge. * At any rate, the theme CSS sets the height and width to 100% so it fits in its column */ if ( isset ( $instance[ 'v_width2' ] ) ) { $instance[ 'v_width2' ] = 340; } if ( isset ( $instance[ 'v_height2' ] ) ) { $instance[ 'v_height2' ] = 200; } } // don't forget to return the widget content return $instance; }
בנוגע לתצוגה – האופן שבו בנויים הוידג’טים הוא כזה שאין hook-ים שמאפשרים לשנות שדות קיימים. יש hook שמאפשר להוסיף שדות אחרים, אבל זה לא מה שרצינו פה. במקרה הזה יש שתי אופציות: או לרשת מה-class של הוידג’ט ולדרוס את פונקציית ה-form שלו, שהיא זו שבונה את ה-HTML של הוידג’ט במסך הוידג’טים ( פירושו של דבר היה בעצם ליצור וידג’ט חדש שיורש מהוידג’ט הקיים, ולהפעיל רק את החדש), או להסתיר את האופציות באמצעות CSS. אנחנו בחרנו במקרה הזה ללכת בדרך השניה – הסתרה ע”י CSS – שהיא אולי פחות אלגנטית מבחינת קוד, אבל עושה את העבודה טוב מספיק (היה לנו מקרה אחר שבו רצינו לשנות בטופס הוידג’ט שדה מסוג טקסט לסדרת שדות מסוג radio button, ואז כן יצרנו וידג’ט חדש).