Thursday 8 December 2011

Page Title in Joomla catalog extension SobiPro

SobiPro is an excellent catalog extension for Joomla - but while working with it I found one missing feature - ability to handle the page title separately.
For categories the Name field is used for page title, breadcrumb, category list and URL. For entries the Entry Title Field selected in the section konfiguration is used for page title, breadcrumb, entry lists and URL.
While this solution seems quite simple it is not SEO friendly. If the page title needs to be changed then the rest is also changed - including the URL which is now different.

I have not found any solution for this - so after spending a few hours I solved it in the backend code.

For category I use the introtext field for the pagetitle. For entry I created a custom field named field_pagetitle.

In the file /joomlaroot/components/com_sobipro/lib/base edit the file config.php and change the method getParentPath to:


public function getParentPath( $id, $names = false, $parents = false, $join = false, $useDescriptions = false )
{
/** @todo We have to implement the MySQL procedure for it */
$db =& SPFactory::db();
if( !( is_numeric( $id ) ) ) {
return false;
}
$ident = 'relations_path' . ( $names ? '_names' : '' ) . ( $parents ? '_parents' : '' ) . ( $join ? '_join' : '' );
$cached = SPFactory::cache()->getVar( $ident, $id );
if( $cached ) {
return $cached;
}
else {
$cid = $id;
}
$path = $parents ? array() : array( $id );
while ( $id > 0 ) {
try {
$db->select( 'pid', 'spdb_relations', array( 'id' => $id ) );
$id = $db->loadResult();
if( $id ) {
$path[] = ( int ) $id;
}
}
catch ( SPException $x ) {
Sobi::Error( __FUNCTION__, SPLang::e( 'CANNOT_GET_PARENT_ID', $x->getMessage() ), SPC::WARNING, 500, __LINE__, __CLASS__ );
}
}
$introtexts;
if( $names && count( $path ) ) {
if ($useDescriptions) {
$names = SPLang::translateObject( $path, 'name', array( 'category' ) );
$introtexts = SPLang::translateObject( $path, 'introtext', array( 'category' ) );
}
else {
$names = SPLang::translateObject( $path, 'name', array( 'section', 'category', 'entry' ) );
}
if( is_array( $names ) && !empty( $names ) ) {
foreach ( $path as $i => $id ) {
if( $join ) {
$path[ $i ] = array( 'id' => $id, 'name' => $names[ $id ][ 'value' ], 'description' => $introtexts[ $id ][ 'value' ] );
}
else {
$path[ $i ] = $names[ $id ][ 'value' ];
}
}
}
}
$path = array_reverse( $path );
SPFactory::cache()->addVar( $path, $ident, $cid );
return $path;
}


In the file /joomlaroot/components/com_sobipro/lib/base edit the file mainframe.php and change the method addObjectToPath to:


public function addObjToPathway( $obj ) {
if( defined( 'SOBI_ADM_PATH' ) ) {
return true;
}
$menu =& JSite::getMenu()->getActive()->query;
$sid = isset( $menu[ 'sid' ] ) ? $menu[ 'sid' ] : 0;
$pathway = & JFactory::getApplication()->getPathway();
if( $obj->get( 'oType' ) == 'entry' ) {
$id = SPRequest::int( 'pid' );
/* if we didn't enetered this entry via category */
if( !$id || $id == Sobi::Section() || Sobi::Cfg( 'entry.primary_path_always' ) ) {
$id = $obj->get( 'parent' );
}
}
else {
$id = $obj->get( 'id' );
}
$path = SPFactory::cache()->getVar( 'parent_path', $id );
if( !( $path ) ) {
$path = SPFactory::config()->getParentPath( $id, true, false, true, true );
SPFactory::cache()->addVar( $path, 'parent_path', $id );
}

if( count( $path ) ) {
/* skip everything above the linked sid */
$rpath = array_reverse( $path );
$path = array();
foreach ( $rpath as $part ) {
if( $part[ 'id' ] == $sid ) {
break;
}
$path[] = $part;
}
$path = array_reverse( $path );
/* ^^ skip everything above the linked sid */
}
$title = array();


if( count( $path ) ) {
foreach ( $path as $data ) {
$title[] = ($data[ 'description' ] != '' ? $data[ 'description' ] : $data[ 'name' ]);
$pathway->addItem( $data[ 'name' ], htmlentities( self::url( array( 'title' => $data[ 'name' ], 'sid' => $data[ 'id' ] ) ) ) );
}
}
if( $obj->get( 'oType' ) == 'entry' ) {
$pathway->addItem( $obj->get( 'name' ), htmlentities( self::url( array( 'task' => 'entry.details','title' => $obj->get( 'name' ), 'sid' => $obj->get( 'id' ) ) ) ) );
$title[] = $obj->get( 'field_pagetitle' );
}
$this->setTitle( $title );
}


Remember to add the field field_pagetitle to the entry and select a different field to the Entry Title Field. Depending on your template you might need to change some things in there too.