קישור לתכנים בג'ומלה

טכניקה לקבלת menu SEF למאמר לפי ה-ID שלו בג'ומלה.

כל מי שעבד על CMS מסוים, בין אם מדובר בוורדפרס, דרופל או ג'ומלה, יודע שלעתים קרובות יש צורך לקשר לדפים מסוימים שה-ID שלהם ידוע לנו. זה יכול להיות מודול שמקשר אל מאמרים נבחרים, מודול שמציג כל פעם מאמר אקראי עם לינק או אפילו יצירת XML שבו יש את הכותרת של התוכן והקישור שלו.

בג'ומלה קל מאד לקשר לתכנים במידה וה-ID של התוכן ידוע, אך מאד קשה למצוא את הקישור שהוא URL Friendly או במונחי ג'ומלה SEF. קישור SEF הוא קישור שבמקום http://joomla.org/index.php?option=com_content&task=view&id=2985&Itemid=33 הוא יראה לי את הקישור הבא: http://www.joomla.org/content/view/2985/33/. ישנם מספר קישורי SEF שאפשר להפעיל – הראשון שבהם הוא alias שבו אני לא אדון כאן ומאפשר לי גישה אל פריט התוכן גם אם הוא לא נמצא בתפריט. השני הוא ה-SEF שנוצר באמצעות שימוש ב-menu. כאשר אני מוסיף פריט מידע כלשהו לתפריט האתר, הוא יוצר לי SEF שבאמצעותו אני יכול לגשת אל פריט המידע שלי.

תזכורת: כך יוצרים פריט מידע בג'ומלה – נכנסים ל'Menus' ואז ל'Menus Manager':

לוחצים על הוספת פריט חדש (סימן הפלוס הירוק הגדול) ואז מגיעים למסך הזה:

וכאן כבר בוחרים את פריט המידע שצריך, במקרה שלי ברוב הפעמים אני בוחר 'article'. לאחר שבחרנו ושמרנו, אנו נראה שיש לנו בתפריט את פריט המידע – בדרך כלל מאמר. המאמר הזה הוא בעל SEF שניתן לו על ידי ה-menu.

באופן שמאד הפתיע אותי, אי אפשר להגיע ל-SEF של ה-menu באמצעות פונקציה/שאילתה פשוטה (לעומת דרופל למשל, שמאפשר לעשות את זה בקלות באמצעות drupal_get_path_alias). אבל מה לעשות שלטובת מנועי החיפוש אני כן צריך להשתמש ב-URL אחיד? לפיכך יש צורך לצלול פנימה אל מסד הנתונים ולהשיג את ה-SEF שלא נשמר יחד עם ה-content (בניגוד ל-alias שכן נשמר) אלא שמור בטבלה שנקראת menu וגם אז צריך להוציא אותו באופן רקורסיבי. בלעחס.

דוגמת הקוד שאני מביא כאן נמצאת ב-class שנקרא myModuleHelper. אני יוצא מנקודת הנחה שאני מקבל id של מאמר מתוך טבלת content ואני צריך למצוא את ה-SEF URL.


<?php
defined('_JEXEC') or die('Direct Access to this location is not allowed.');
 
class myModuleHelper
{
  
    public function getMyMenuSEF($contentId) {
    	$db = &JFactory::getDBO();
    	$query = "SELECT id FROM #__menu where link LIKE \"%$contentId\" LIMIT 1";
        $db->setQuery($query);
        $result = ($items = $db->loadObjectList())?$items:array();
		$menuItemId = $result[0]->id; 
        return myModuleHelper::getMyMenuURL($menuItemId);
    }
    
    private function getMyMenuURL($menuItemId) {
    	$url = array();
    	$i = false;
    	while($i == false) {
    	$item = myModuleHelper::getMyAliasAndParent ($menuItemId);
	    	if($item->parent != 0) {
	 			$url[] = $item->alias;
	 			$menuItemId = $item->parent;
	    	}
	    	else {
	    		$url[] = $item->alias;	
	    		$i = true;
	    	}
    	}
    	$url = array_reverse($url);
    	$url = implode('/', $url);
    	return $url;
    }
    
    private function getMyAliasAndParent ($menuItemId) { //Getting the alias and parent
    	$db = &JFactory::getDBO();
    	$query = "SELECT alias, parent FROM #__menu where id = $menuItemId LIMIT 1";
        $db->setQuery($query);
        $results = ($items = $db->loadObjectList())?$items:array();

    	if($results) {
        	return $results[0];
    	}
    	else {
    		return null;
    	}
    }
} 

כפי שניתן לראות מדובר בקוד מסובך הרבה יותר – ראשית אני מקבל את ה-id של ה-content ואז מוצא באמצעותו את ה-id של ה-menu ואת זה רק באמצעות LIKE ל-URL שיש ב-menu, אחרי כן פונקציה רקורסיבית עוברת על כל ההורים ומרכיבה מהם את ה-SEF URL. התוצאה היא ה-URL.

אם יש לי מודול, אני אשתמש בשורות הבאות להכליל את myModuleHelper (ששמור בשם myModuleHelper.php באותה תיקיה), ליצור template ולאפשר לו להשתמש במשתנה
itemLink.


// get the item link to display from the helper
$itemLink = myModuleHelper::getMyMenuSEF($ContentID);
// include the template for display
require(JModuleHelper::getLayoutPath('mod_Template'));

אם למישהו מהקוראים יש פתרון יותר אלגנטי לקבלת SEF של menuitem לפי content id – אשמח לדעת על כך!

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

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

עבודה עם GPT למתכנתים

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

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