אחת הדרכים המובילות בדרופל 6 (ודרופל 7) לבצע שינויים באלמנטים שונים היא להשתמש בפונקצית theme. כך למשל, אם אני רוצה לשנות את הדרך שבה checkbox מוצג באתר אני אקח את פונקצית theme_checkbox שיש בדוקומנטציה, אעתיק אותה ל-template.php ואשנה את השם שלה בהתאם ל-theme שאני משתמש בו וכך אוכל לשנות את הפונקציה ובכל checkbox שמוצג הפונקציה שלי תרוץ.
בעוד שהשיטה הזו לגיטימית, היא בעייתית משתי סיבות עיקריות:
1. זה גורם להתנפחות ה-template.php
2. כאשר אני בונה מודול, אני לא יכול לבקש מהמשתמש להכניס theme.
סעיף 2 יותר חשוב לי, אני אוהב לבנות את המודולים שלי כקופסאות סגורות – גם אם זה מודולים ייעודיים שאני מפתח המיועדים לאתר אחד. אני לא רוצה לסמוך על זה שיש פונקצית theme ב-template.php. מחר בבוקר ירצו לשנות את התמה או לשדרג ואז מה? עדיף שכל מה שקשור למודול יהיה בתוך המודול.
למרבה המזל, קל מאד לקרוא לפונקצית theme באמצעות מודול. לדרופל יש רגי'סטרי – רשימת פונקציות theme, המודול שלי יכנס לרג'יסטרי וישנה את פונקצית ה-theme שרצה לפונקציה קיימת בתוך המודול.
נשמע מסובך? הכל פשוט עם דוגמא. מה שהמודול שלי עושה הוא לשנות את ה-checkbox לצורך כלשהו. אני צריך שהפונקציה שלי תרוץ במקום theme_checkbox.
ראשית, אני אגש לדוקומנטציה ואעתיק את פונקצית theme_checkbox. את הפונקציה אני אדביק במודול שלי ואקרא לה בשם ארביטרארי נוסח MY_MODULE_checkbox. לא לשכוח לשמור את הארגומנטים!
אחרי כן אני אשתמש ב-hook_theme_registry_alter על מנת לשנות את פונקצית ה-theme ל-MY_MODULE_checkbox.
בדיוק כך:
/**
* Implementation of hook_theme_registry_alter().
*
* @param $theme_registry The entire cache of theme registry information, post-processing.
*/
function MY_MODULE_theme_registry_alter(&$theme_registry) {
if (!empty($theme_registry['checkbox'])) {
$theme_registry['checkbox']['function'] = 'MY_MODULE_checkbox';
}
}
/**
* MY_MODULE implementation of theme_checkbox
* @param $element the checkbox element
*/
function MY_MODULE_checkbox($element) {
_form_set_class($element, array('form-checkbox'));
$checkbox = '<input ';
$checkbox .= 'type="checkbox" ';
$checkbox .= 'name="' . $element['#return_value'] . '" ';
$checkbox .= 'id="' . $element['#id'] . '" ';
$checkbox .= 'value="' . $element['#return_value'] . '" ';
$checkbox .= $element['#value'] ? ' checked="checked" ' : ' ';
$checkbox .= drupal_attributes($element['#attributes']) . ' />';
if (!is_null($element['#title'])) {
$checkbox = '<label class="option" for="' . $element['#id'] . '">' . $checkbox . ' ' . $element['#title'] . '</label>';
}
unset($element['#title']);
return theme('form_element', $element, $checkbox);
}
וזה הכל, אל תתביישו לחקור את הרג'יסטרי כדי לראות עוד איזה אלמנטים אפשר לדרוס.