248 Posts
Giuse
4 years ago
2
Topic

If some of you is using multilanguage features from Seblod so instead of cloning articles in the Joomla core way, you are creating one article for all language with language set to "*" and then use JText, restrictions and so on to translate fields or show only fields in current language, you know that you are loosing the hreflang tag in the head of your content pages, since Joomla language filter plugin cannot build them since it does not find article assocations among languages and since the Seblod router is different than Joomla one.

For this purpose I wrote a small php code that does that: in the single Seblod article view, it adds the hreflang in all languages and the xdefault one. You can just put it in a custom module using some plugin that allows you to put php code in a module, like the well-known Sourcerer. Or you can put it in a system plugin for a more elegant way.

Here it is for who is interested (the first and last line is needed to put php code using Sourcerer).

{source}<?php

$app = JFactory::getApplication();

$myInput = $app->input;

$languages = JLanguage::getKnownLanguages();

// if current page is a single joomla article view and site is multilanguage

if ($myInput->get('option') == "com_content" && $myInput->get('view') == "article" && count($languages) > 1)

 {

 $ids = explode(':',$myInput->getString('id'));

 $article_id = $ids[0];

 $article = JTable::getInstance("content");

 $article->load($article_id);

 $art_id = $article->get("id");

 // if the article is stored as multilang => go on

 if($article->get("language") == "*")

  {

  // get raw URL of current menu

  $Itemid = $myInput->get('Itemid');

  $menuUrl = $app->getMenu()->getItem($Itemid)->link;

  // if current page is under a Seblod list => we are in the right case, go!

  if(strcmp($menuUrl, "index.php?option=com_cck&view=list") != false)

   {

   $server = JUri::getInstance()->toString(array('scheme', 'host', 'port'));

   $defLang = JFactory::getLanguage()->getDefault();

   // retrieve menu item associations

   $assoc = MenusHelper::getAssociations($Itemid);

   foreach ($languages as $i => $language)

    {

    $newUrl = JRoute::_("index.php?Itemid=" . $assoc[$i] . "&view=article&id=" . $article_id . "&lang=" . $i);

    $doc->addHeadLink($server . $newUrl, 'alternate', 'rel', array('hreflang' => $i));

    // if it’s also default lang => set it (addHeadLink is limited to 1 URI per tag)

    if($i == $defLang)

     {

     $doc->addCustomTag('<link href="' . $server . $newUrl . '" rel="alternate" hreflang="x-default" />');

     }

    }

   }

  }

 }

?>{/source}

Giuse

Get a VIP membership
215 Posts
iliil
4 years ago
1
Level 1

Hi Giuse. 

Great, thanks!

Just an enhancement idea:

If you put the code into the SEBLOD beforeRender field,  you don't have to load the article data from the database again, all article data is available in the variables $fields or $config. there already.  e.g. article id is stored in $config['pk'].

Best ;)

Michal

248 Posts
Giuse
4 years ago
0
Level 2

Thanks Michal. For a before render field put in a Content View and assuming that some checks can be skipped (to be in a com_content, single article view, under a list menu item), the code would be just

$article_lang = $config['storages']['#__content']->language;
// if the article is stored as multilang => go on
if($article_lang == "*")
{
$app = JFactory::getApplication();
$doc = JFactory::getDocument();
$languages = JLanguage::getKnownLanguages();
$article_id = $config['pk'];
$Itemid = $config['Itemid'];
$server = JUri::getInstance()->toString(array('scheme', 'host', 'port'));
$defLang = JFactory::getLanguage()->getDefault();
// retrieve menu item associations passing a string
$assoc = MenusHelper::getAssociations($Itemid . "");
foreach ($languages as $i => $language)
  {
  $newUrl = JRoute::_("index.php?Itemid=" . $assoc[$i] . "&view=article&id=" . $article_id . "&lang=" . $i);
  $doc->addHeadLink($server . $newUrl, 'alternate', 'rel', array('hreflang' => $i));
  // if it is also default lang => set it (addHeadLink is limited to 1 URI per tag)
  if($i == $defLang)
   {
   $doc->addCustomTag('<link href="' . $server . $newUrl . '" rel="alternate" hreflang="x-default" />');
   }
  }
}

Of course using it in a field means you have to put in all your content types while as a module it is already activated for all (even when not to be used :)).

cheers

Giuse

Get a VIP membership