מודול related articles בדרופל 6 ודרופל 7

שימוש נבון במודול Taxonomy בדרופל יכול לעשות חיים קלים במיוחד - גם בתחום מיון המידע וגם בתחום יצירת בלוק של Related articles.

Taxonomy בדרופל היא מודול core נפלא שמאפשר לנו לתייג ולסמן כל תוכן שהוא כאוות נפשנו. מדובר במודול נפלא ושימושי להפליא שאנו יכולים להשתמש בו למגוון דברים – אנו יכולים למשל לקבוע Taxonomy type אחד שישמש לנו כקטגוריה. אנו יכולים לקבוע את משנהו כבסיס למערכת תיוג חופשית יותר כמו בבלוגים. אפשר לבצע טקסונומיה היררכית ואפשר לתת לכל מאמר כמה תגים שרוצים (אלא אם כן אנו מגבילים זאת מראש במערכת).

אם הטמענו את Taxonomy בהיררכית המידע שלנו בחוכמה, נוכל להשתמש ב-Taxonomy גם כבסיס ל-View. במקום ליצור View בנפרד לכל קטגוריה, אנו ניצור View אחד שיקח כפרמטר את ה-Taxonomy ID ויריץ שאילתה על מנת להעלות בחכתו את כל התכנים שמשתמשים באותה תגית.

אחד מהדברים הנפלאים שאפשר לעשות עם Taxonomy בקלות הוא בניית בלוק שיביא לנו כמות מסוימת של תכנים שקשורים לתוכן שלנו.

אני מניח שאתם יודעים מספיק על בניית מודולים בדרופל 6 ו-7 כדי לא לעבור על קובץ ה-info אלא להתרכז בקובץ ה-module בלבד. אם לא – הנה מאמר קצר על בניית מודולים לדרופל 6/7.

יצירת הבלוק


/*
 * hook_block - creating the block
 */

function myblock_related_articles_block($op = 'list', $delta = 0, $edit = array()) {

	if($op == "list") {  //Create block on block admin
		 $blocks[0] = array('info' => t('Related Articles'),
      						'weight' => 1, 
      						'status' => 1, 
      						'region' => 'sidebar_first',
		 					'delta' => 0,
		 				);	
		return $blocks;
	}
	
	else if ($op == 'view' && ((arg(0)=='node') && is_numeric(arg(1)) && !arg(2))) { //Create block content
	    switch($delta) {
	      case 0:
	      	$block = array('subject' => t('Related Articles'),
	          			   'content' => _related_article(),
	      					);
	        break;
	    }
  		return $block;
	}
}


יצירת הבלוק נעשית באמצעות hook_block. באמצעות ה-op אני יוצר את המודול בממשק הניהול (op=list) ובאתר עצמו (op=view). שימו לב שבאתר עצמו הוספתי תנאי שמגביל את הצגת הבלוק למתי שהארגומנט הראשון הוא node והארגומנט השני הוא מספר – זה נעשה על מנת להציג את הבלוק במאמרים בלבד ולא ב-Views או במקומות אחרים. יצירת התוכן היא באחריות פונקצית related_article_ שנראית כך:

יצירת התוכן של הבלוק


/*
 * block content generator and css adding
 */

function _related_article() {
	
	drupal_add_css(drupal_get_path('module', 'myblock_related_articles') .'/myblock_related_articles.css');
	
	$result = taxonomy_select_nodes(get_args(), 'or',  0, TRUE, $order = 'n.created DESC');
	while ($obj = db_fetch_object($result)) {
		$node = node_load(array('nid' => $obj->nid));
		$items[] = l($node->title, "node/". $node->nid);
		}
	return theme('item_list', $items);
}

הפונקציה related_article_ מכניסה CSS מותאם לבלוק (שאותו אצור אחר כך ואכניס לתיקיה). אני אוהב מאד ליצור CSS לכל בלוק בנפרד ולא להכניס את כולם בתוך CSS כללי. ראשית, זה יוצר סוג של קופסה שאני יכול להעביר לפרויקט אחר ושנית זה לא טוען את ה-CSS כאשר הבלוק לא בשימוש.

משתנה ה-result$ מקבל לעצמו resource שמגיע משאילתה על מסד הנתונים שמתבצעת באמצעות פונקצית taxonomy_select_nodes. אני ארחיב על פונקציה זו בהמשך כיוון שהיא 'לב המערכת'.
את ה-resource אנו מפרקים באמצעות while. ה-resource מכיל בעצם את כל ה-node האחרונים (לפי תאריך הפרסום) עם הפרטים עליהם. אני יוצר מערך של הפרטים שאני רוצה (במקרה הזה קישורים ל-titleים, אני משתמש בפונקצית l על מנת לייצר את הקישור).
את המערך לבסוף אני מייצר כרשימה באמצעות פונקצית theme.

יצירת השאילתה באמצעות פונקצית taxonomy_select_nodes


function get_args() {
	if((arg(0)=='node') && is_numeric(arg(1)) && !arg(2)) {
		$node = node_load(arg(1));
		$terms =  taxonomy_node_get_terms($node);
		foreach($terms as $term) {
			$tids[] = $term->tid;
		}		
		return $tids;
	}
}

הפונקציה הזו משמשת אותי ליצירת מערך של Taxonomy id (tid) שאותה אוכל לטעון לפונקצית taxonomy_select_nodes שתחזיר לי את ה-resource. הפונקציה פשוטה ביותר. לאחר שאני מוודא שהארגומנטים שלי תקינים, אני אטען את ה-node שלי ואקח את ה-taxonomy שלו באמצעות taxonomy_node_get_terms ומשם לתוך מערך שאותו אני מחזיר ל-taxonomy_select_nodes.

והנה הקוד המלא:


< ?php
// $Id: myblock_related_articles.module,v 1.15 2010/11/08 17:47:51  Exp $

/*
 * hook_block - creating the block
 */

function myblock_related_articles_block($op = 'list', $delta = 0, $edit = array()) {

	if($op == "list") {  //Create block on block admin
		 $blocks[0] = array('info' => t('Related Articles'),
      						'weight' => 1, 
      						'status' => 1, 
      						'region' => 'sidebar_first',
		 					'delta' => 0,
		 				);	
		return $blocks;
	}
	
	else if ($op == 'view' && ((arg(0)=='node') && is_numeric(arg(1)) && !arg(2))) { //Create block content
	    switch($delta) {
	      case 0:
	      	$block = array('subject' => t('Related Articles'),
	          			   'content' => _related_article(),
	      					);
	        break;
	    }
  		return $block;
	}
}

/*
 * block content generator and css adding
 */

function _related_article() {
	
	drupal_add_css(drupal_get_path('module', 'myblock_related_articles') .'/myblock_related_articles.css');
	
	$result = taxonomy_select_nodes(get_args(), 'or',  0, TRUE, $order = 'n.created DESC');
	while ($obj = db_fetch_object($result)) {
		$node = node_load(array('nid' => $obj->nid));
		$items[] = l($node->title, "node/". $node->nid);
		}
	return theme('item_list', $items);
}

/*
 * Getting all TID that related to the node
 */

function get_args() {
	if((arg(0)=='node') && is_numeric(arg(1)) && !arg(2)) {
		$node = node_load(arg(1));
		$terms =  taxonomy_node_get_terms($node);
		foreach($terms as $term) {
			$tids[] = $term->tid;
		}		
		return $tids;
	}
}

דרופל 7

בדרופל 7 יש לנו כמה התאמות שאנו צריכים לעשות. ראשית, hook_block הולך להשתנות באופן דרמטי, יש לפצל אותו לשני ה-op. גם drupal_add_css משתנה אבל לא באופן שאנו צריכים לשנות את הפונקציה. יש שינויים גם ב-node_load אבל באופן מינורי שדורש מאיתנו לשנות את ה-input בלבד. ככה זה נראה:


< ?php
// $Id: myblock_related_articles.module,v 1.15 2010/11/08 17:47:51  Exp $

/*
 * hook_block - creating the block for the admin interface
 */

function myblock_related_articles_block_info() {
	$blocks[0] = array('info' => t('Related Articles'),
						'weight' => 1, 
						'status' => 1, 
						'region' => 'sidebar_first',
						'delta' => 0,
					);	
	return $blocks;
}

/*
 * hook_block - creating the block for the view
 */
 
function myblock_related_articles_block_view ($delta = '') {
switch($delta) {
	      case 0:
	      	$block = array('subject' => t('Related Articles'),
	          			   'content' => _related_article(),
	      					);
	        break;
	    }
  		return $block;
}
 

/*
 * block content generator and css adding
 */

function _related_article() {
	
	drupal_add_css(drupal_get_path('module', 'myblock_related_articles') .'/myblock_related_articles.css');
	
	$result = taxonomy_select_nodes(get_args(), FALSE, FALSE, $order = array('t.created' => 'DESC'))
	while ($obj = db_fetch_object($result)) {
		$node = node_load($obj->nid);
		$items[] = l($node->title, "node/". $node->nid);
		}
	return theme('item_list', $items);
}

/*
 * Getting all TID that related to the node
 */

function get_args() {
	if((arg(0)=='node') && is_numeric(arg(1)) && !arg(2)) {
		$node = node_load(arg(1));
		$terms =  taxonomy_node_get_terms($node);
		foreach($terms as $term) {
			$tids[] = $term->tid;
		}		
		return $tids;
	}
}

זה הכל.

פוסטים נוספים שכדאי לקרוא

תמונה מצוירת של רובוט שמנקה HTML
יסודות בתכנות

סניטציה – למה זה חשוב

הסבר על טכניקה פשוטה וידועה מאד שאנו מפעילים על מידע לפני שאנחנו מציגים אותו ב-HTML באפליקציה או באתר.

פתרונות ומאמרים על פיתוח אינטרנט

נגישות טכנית – פודקאסט ומבוא

פרק בפודקאסטעל נגישות בעברית שצולל לכלים האוטומטיים ולפן המאד מאד טכני של הנגישות.

פתרונות ומאמרים על פיתוח אינטרנט

המנעו מהעלאת source control לשרת פומבי

לא תאמינו כמה אתרים מעלים את ה-source control שלהם לשרת. ככה תמצאו אותם וגם הסבר למה זה רעיון רע.

גלילה לראש העמוד