Jump to content
Remitur

Knowledge base, friendly URLs and multilanguage

Recommended Posts

With friendly URL enabled and multilanguage enabled, if you translate your kb posts you'll get, i.e.:

https://yourwhmcs.ext/index.php?rp=/knowledgebase/55/How-to-boil-water.html    (English, default language)

and

https://yourwhmcs.ext/index.php?rp=/knowledgebase/55/Come-bollire-l-acqua.html   (italian version)

Right, nice.

The issue?

If I send the italian link to someone who is no logged in, he will have set the default language, so when he click on https://yourwhmcs.ext/index.php?rp=/knowledgebase/55/Come-bollire-l-acqua.html he will bring to the same page but... in the english (default language) version!!!!

If he select the right language, he will bring to home page... and he should now again recover the link, click on it, and finally he'll get the right page in italian version... :-/

Dirty fix: modify the link sent to the user, adding &language=italian ; so sending i.e.

https://yourwhmcs.ext/index.php?rp=/knowledgebase/55/Come-bollire-l-acqua.html&language=italian 

it works fine, but it's annoying because you are required to edit manually the link before sending it ... 😕

Anyone has any better idea? A hook, a trick, some kind of .htaccess rewrite in order to get a better result? 

 

Share this post


Link to post
Share on other sites

 I suppose you could get the title of the article, query the tblkb table and see if there's a language assigned to the article and redirect to the correct language with a hook.... though whether that's worth doing, I don't know.

Share this post


Link to post
Share on other sites
3 hours ago, brian! said:

 I suppose you could get the title of the article, query the tblkb table and see if there's a language assigned to the article and redirect to the correct language with a hook.... though whether that's worth doing, I don't know.

Exactly.

@Remitur The problem is that WHMCS language is based on sessions so it doesn't matter what's the URL. The article will always use the default language which in your case is English. This hook should work. I tested on my dev system lazily. I'm gonna update if it doesn't work. It's commented. More information are provided below.

<?php

use WHMCS\Database\Capsule;
use WHMCS\Config\Setting;

add_hook('ClientAreaPageKnowledgebase', 1, function($vars)
{
	/**
	* The way I'm getting $ArticleLanguage looks complicated but is necessary to match "Hello hello-hello" title with the rewritten URLs "Hello-hello-hello"
	* In fact there's no way to distinguish real dashes "-" from fake ones added by Friendly URLs of WHMCS
	* Keep in mind that I'm forced to use "raw" static method since WHERE statement doesn't support complex functions like REPLACE
	*/

	// Getting title from querty string
	$PageName = pathinfo($_GET['rp'])['filename'];
	// Retreiving the language of the currently displayed article by ID and title
	$ArticleLanguage = Capsule::select(Capsule::raw('SELECT language FROM tblknowledgebase WHERE parentid = "' . $vars['kbarticle']['id'] . '" AND REPLACE(title, "-", " ") = "' . str_replace('-', ' ', $PageName) . '" LIMIT 1'))[0]->language;
	// Retreiving the default language of WHMCS from tblconfiguration
	$DefaultLanguage = Setting::getValue('Language');

	/**
	 * This section is optional but needed if you want to protect yourself against blackhat SEO techniques (read post for more info)
	 */

	// Retreiving default language title
	$LegitURL = Capsule::select(Capsule::raw('SELECT REPLACE(title, " ", "-") AS title FROM tblknowledgebase WHERE id = "' . $vars['kbarticle']['id'] . '" LIMIT 1'))[0]->title;

	// If the URL currently in use is not 100% legit I force a redirect to the article in default langiage
	if ($LegitURL !== $PageName AND !$ArticleLanguage)
	{
		header('Location: index.php?rp=/knowledgebase/' . $vars['kbarticle']['id'] . '/' . $LegitURL . '.html');
		die();
	}

	/**
	 * Here we set the right language depending on the URL
	 */

	// I check if the $ArticleLanguage is different from the language currently in use. I also make sure that $ArticleLanguage is different from $_SESSION['Language'] to avoid infinite loops
	if ($ArticleLanguage != $DefaultLanguage AND $ArticleLanguage != $_SESSION['Language'])
	{
		// Set language
		$_SESSION['Language'] = $ArticleLanguage;
		// Redirect visitor to current page to re-load the correct language 
		header('Location: index.php?rp=' . $_GET['rp']);
		die();
	}
});

add_hook('ClientAreaHeadOutput', 1, function($vars)
{
	/**
	 * This guy adds canonical URL inside <head></head> tag so that Google doesn't penalize you (read post for more info) 
	 */

	if ($vars['templatefile'] == 'knowledgebasearticle')
	{
		$PageName = pathinfo($_GET['rp'])['filename'];
		$CanonicalURL = Capsule::select(Capsule::raw('SELECT REPLACE(title, " ", "-") AS title FROM tblknowledgebase WHERE (parentid = "' . $vars['kbarticle']['id'] . '" OR id = "' . $vars['kbarticle']['id'] . '") AND REPLACE(title, "-", " ") = "' . str_replace('-', ' ', $PageName) . '" LIMIT 1'))[0]->title;

		return '<link rel="canonical" href="index.php?rp=/knowledgebase/' . $vars['kbarticle']['id'] . '/' . $CanonicalURL . '.html"/>';
	}
});

Even though we're now showing the right language to visitors, Google and all other Search Engines still hate us because we're providing duplicate contents. Their hate is so strong that they penalize us on SERP. Here is why:

  • whmcs.com/index.php?rp=/knowledgebase/55/How-to-boil-water.html
  • whmcs.com/index.php?rp=/knowledgebase/55/How-to-boil-vodka.html
  • whmcs.com/index.php?rp=/knowledgebase/55/How-to-boil-rum.html
  • whmcs.com/index.php?rp=/knowledgebase/55/How-to-boil-wine.html

4 URLs, same page and (duplicate) content. The only way to avoid penalties is that we let them know what's the unique URL by using rel="canonical" tag. The above hook adds it automatically where it is supposed to be (<head>here</head>). And if you are questioning why someone should use fake links, take a look at blackhat SEO techniques. One of your malicious competitor could publish some of those fake-links so that weeks later Google & co. penalize you for duplicate content. The above hook protects you from this technique forcing a redirect to the default article in case the URL in use is not the legit one.

Share this post


Link to post
Share on other sites
Posted (edited)

I don't know why I can no longer edit my own post so I'm gonna repost an updated version of the above script. In fact I noticed a small issue.

<?php

use WHMCS\Database\Capsule;
use WHMCS\Config\Setting;

add_hook('ClientAreaPageKnowledgebase', 1, function($vars)
{
	/**
	* The way I'm getting $ArticleLanguage looks complicated but is necessary to match "Hello hello-hello" title with the rewritten URLs "Hello-hello-hello"
	* In fact there's no way to distinguish real dashes "-" from fake ones added by Friendly URLs of WHMCS
	* Keep in mind that I'm forced to use "raw" static method since WHERE statement doesn't support complex functions like REPLACE
	*/

        if (!$vars['kbarticle']['id']): return; endif;

	// Getting title from querty string
	$PageName = pathinfo($_GET['rp'])['filename'];
	// Retreiving the language of the currently displayed article by ID and title
	$ArticleLanguage = Capsule::select(Capsule::raw('SELECT language FROM tblknowledgebase WHERE parentid = "' . $vars['kbarticle']['id'] . '" AND REPLACE(title, "-", " ") = "' . str_replace('-', ' ', $PageName) . '" LIMIT 1'))[0]->language;
	// Retreiving the default language of WHMCS from tblconfiguration
	$DefaultLanguage = Setting::getValue('Language');

	/**
	 * This section is optional but needed if you want to protect yourself against blackhat SEO techniques (read post for more info)
	 */

	// Retreiving default language title
	$LegitURL = Capsule::select(Capsule::raw('SELECT REPLACE(title, " ", "-") AS title FROM tblknowledgebase WHERE id = "' . $vars['kbarticle']['id'] . '" LIMIT 1'))[0]->title;

	// If the URL currently in use is not 100% legit I force a redirect to the article in default langiage
	if ($LegitURL !== $PageName AND !$ArticleLanguage)
	{
		header('Location: index.php?rp=/knowledgebase/' . $vars['kbarticle']['id'] . '/' . $LegitURL . '.html');
		die();
	}

	/**
	 * Here we set the right language depending on the URL
	 */

	// I check if the $ArticleLanguage is different from the language currently in use. I also make sure that $ArticleLanguage is different from $_SESSION['Language'] to avoid infinite loops
	if ($ArticleLanguage != $DefaultLanguage AND $ArticleLanguage != $_SESSION['Language'])
	{
		// Set language
		$_SESSION['Language'] = $ArticleLanguage;
		// Redirect visitor to current page to re-load the correct language 
		header('Location: index.php?rp=' . $_GET['rp']);
		die();
	}
});

add_hook('ClientAreaHeadOutput', 1, function($vars)
{
	/**
	 * This guy adds canonical URL inside <head></head> tag so that Google doesn't penalize you (read post for more info) 
	 */

	if ($vars['templatefile'] == 'knowledgebasearticle')
	{
	        if (!$vars['kbarticle']['id']): return; endif;

		$PageName = pathinfo($_GET['rp'])['filename'];
		$CanonicalURL = Capsule::select(Capsule::raw('SELECT REPLACE(title, " ", "-") AS title FROM tblknowledgebase WHERE (parentid = "' . $vars['kbarticle']['id'] . '" OR id = "' . $vars['kbarticle']['id'] . '") AND REPLACE(title, "-", " ") = "' . str_replace('-', ' ', $PageName) . '" LIMIT 1'))[0]->title;

		return '<link rel="canonical" href="index.php?rp=/knowledgebase/' . $vars['kbarticle']['id'] . '/' . $CanonicalURL . '.html"/>';
	}
});

 

Edited by Kian

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated