polskie znaki w adresach Joomla SEF URL 2

Joomla w wersji 1.5 posiada przyjazne adresy nazwane skrótowo SEF URL’s (ang. seo friendly URL). Mankamentem tej opcji jest to, że polskie znaki są po prostu opuszczane przy zamienianiu tytułu na alias wykorzystywany w przyjaznych adresach. I tak mając tytuł Zażółć gęślą jaźń powinien zostać przekształcony na alias w postaci zazolc-gesla-jazn natomiast domyślnie Joomla zrobi nam z tego ciąg nieprzypominający zupełnie oryginału za-g-l-ja. Joomla 1.6 jest wolna od tej niedoróbki, transliteruje większość znaków z łacińskiego alfabetu – łacińskopochodnych.

Brak polskich znaków w adresie Joomla

Brak polskich znaków w adresach i aliasach Joomli

Polskie znaki w adresach internetowych nie powinny być używane (mam nadzieję, że popularyzacja Unicode’u to zmieni) dlatego też każdy polski znak zamienia się na jego wizualny odpowiednik bez ogonka z kodowania ASCII. To samo tyczy się pustych znaków jak spacja, tyle że takie puste znaki oraz inne nie będące literą lub cyfrą są opuszczane a odstępy między wyrazami są zamienne na myślniki. Jest to najbardziej popularny format linków i chyba najbardziej czytelny oraz na pewno najmniej problemowy.

Polskie znaki w adresach i aliasach Joomla

Przy pisaniu tej funkcji wykorzystałem tablice i mój dawny twór usuwanie znaków specjalnych z kodowania latin2 jest tam funkcja która bardzo ładnie przygotowuje ciąg do użycia w adresie URL. Przekonwertowałem tablice do kodowania UTF-8 i zapisałem w formacie szesnastkowym więc nie ma znaczenia w jakim kodowaniu zapiszesz i tak będzie działać – ot taka przewaga nad żywymi / widocznymi polskimi znakami oraz zamienia wszystkie ogonkowe znaki jakie istnieją w kodowaniu ISO-8859-2 więc sporo więcej niźli tylko polskie znaki (np. znaki z niemieckiego alfabetu).

Polskie znaki w aliasach Joomla

Naprawiona obsługa i tworzenie aliasów oraz URL'i z polskimi znakami w Joomla

Po zainstalowaniu tej poprawki aliasy będą już poprawnie zapisywane z zamienionymi polskimi znakami.

Otwórz plik /libraries/joomla/filter/filteroutput.php i znajdź w nim

	function stringURLSafe($string)
	{
		//remove any '-' from the string they will be used as concatonater
		$str = str_replace('-', ' ', $string);
 
		$lang =& JFactory::getLanguage();
		$str = $lang->transliterate($str);
 
		// remove any duplicate whitespace, and ensure all characters are alphanumeric
		$str = preg_replace(array('/\s+/','/[^A-Za-z0-9\-]/'), array('-',''), $str);
 
		// lowercase and trim
		$str = trim(strtolower($str));
		return $str;
	}

całą tę funkcję zamień na:

	function stringURLSafe($string)
	{
		$map1 = array (
			"\xc4\x84", "\xc5\x81", "\xc4\xbd", "\xc5\x9a",
			"\xc2\xa7", "\xc5\xa0", "\xc5\x9e", "\xc5\xa4",
			"\xc5\xb9", "\xc5\xbd", "\xc5\xbb", "\xc4\x85",
			"\xc5\x82", "\xc4\xbe", "\xc5\x9b", "\xc5\xa1",
			"\xc5\x9f", "\xc5\xa5", "\xc5\xba", "\xc5\xbe",
			"\xc5\xbc", "\xc5\x94", "\xc3\x81", "\xc3\x82",
			"\xc4\x82", "\xc3\x84", "\xc4\xb9", "\xc4\x86",
			"\xc3\x87", "\xc4\x8c", "\xc3\x89", "\xc4\x98",
			"\xc3\x8b", "\xc4\x9a", "\xc3\x8d", "\xc3\x8e",
			"\xc4\x8e", "\xc4\x90", "\xc5\x83", "\xc5\x87",
			"\xc3\x93", "\xc3\x94", "\xc5\x90", "\xc3\x96",
			"\xc3\x97", "\xc5\x98", "\xc5\xae", "\xc3\x9a",
			"\xc5\xb0", "\xc3\x9c", "\xc3\x9d", "\xc5\xa2",
			"\xc3\x9f", "\xc5\x95", "\xc3\xa1", "\xc3\xa2",
			"\xc4\x83", "\xc3\xa4", "\xc4\xba", "\xc4\x87",
			"\xc3\xa7", "\xc4\x8d", "\xc3\xa9", "\xc4\x99",
			"\xc3\xab", "\xc4\x9b", "\xc3\xad", "\xc3\xae",
			"\xc4\x8f", "\xc4\x91", "\xc5\x84", "\xc5\x88",
			"\xc3\xb3", "\xc3\xb4", "\xc5\x91", "\xc3\xb6",
			"\xc5\x99", "\xc5\xaf", "\xc3\xba", "\xc5\xb1",
			"\xc3\xbc", "\xc3\xbd", "\xc5\xa3",
		);
		$map2 = array (
			"\x41", "\x4c", "\x4c", "\x53", "\x53", "\x53",
			"\x53", "\x54", "\x5a", "\x5a", "\x5a", "\x61",
			"\x6c", "\x6c", "\x73", "\x73", "\x73", "\x74",
			"\x7a", "\x7a", "\x7a", "\x52", "\x41", "\x41",
			"\x41", "\x41", "\x4c", "\x43", "\x43", "\x43",
			"\x45", "\x45", "\x45", "\x45", "\x49", "\x49",
			"\x44", "\x44", "\x4e", "\x4e", "\x4f", "\x4f",
			"\x4f", "\x4f", "\x78", "\x52", "\x55", "\x55",
			"\x55", "\x55", "\x59", "\x54", "\x73\x73",
			"\x72", "\x61", "\x61", "\x61", "\x61", "\x6c",
			"\x63", "\x63", "\x63", "\x65", "\x65", "\x65",
			"\x65", "\x69", "\x69", "\x64", "\x64", "\x6e",
			"\x6e", "\x6f", "\x6f", "\x6f", "\x6f", "\x72",
			"\x75", "\x75", "\x75", "\x75", "\x79", "\x74",
		);
		$string = str_replace($map1,$map2,$string);
		$string = strtolower($string);
		$string = preg_replace('#[\\W]{1,}#','-',$string);
		$string = trim($string);
		$string = trim($string,'-');
		$string = trim($string);
		return $string;
	}

Zapisz plik i wgraj na serwer FTP, aliasy będą tworzone poprawnie.

Adres z polskimi znakami Joomla

Pasek adresu z poprawnymi polskimi znakami w adresie w Joomli

Automatyczna naprawa wszystkich aliasów i adresów

Otóż gdy mamy już błędnie zapisane aliasy to mamy do wyboru albo automatyczną naprawę albo edytować każdy artykuł / kategorię etc. i usunąć zawartość aliasu wtedy po zapisaniu z pustym aliasem zostanie utworzony nowy od tytułu ale już z poprawnymi polskimi znakami dzięki funkcji wyżej.

Wygodniejsze jest poprawienie wszystkich aliasów z automatu w tym celu stworzyłem skrypt PHP, który to wykona za nas. Mam nadzieję, że nie pominąłem żadnych aliasów. Wszystkie tabele, w których poprawia aliasy są w tablicy $tables. Aliasy są tworzone według tytułów i przeparsowane do odpowiedniego formatu. Poniższy skrypt należy zapisać jako aliaser.php i wgrać do głównego folderu Joomli a następnie wywołać go w przeglądarce. Jeżeli portal jest bardzo duży należy dorobić limit pobrań danych z mysql’a. Uwaga: ten skrypt nadpisze wszelkie aliasy niezależnie od tego czy były zmieniane ręcznie czy też nie. Po użyciu skryptu wyczyść pamięć podręczną.

<?php
 
setlocale(LC_ALL, 'pl_PL');
date_default_timezone_set('Europe/Warsaw');
if(!include(rtrim(dirname(__FILE__),'/').'/configuration.php')){
	die('Brak pliku configuration.php');
}
 
$cnf = new JConfig();
$user = $cnf->user;
$pass = $cnf->password;
$dbname = $cnf->db;
$host = $cnf->host;
$prefix = $cnf->dbprefix;
 
$link = mysql_connect($host, $user, $pass) or die('Blad polaczenia z baza mysql: ' . mysql_error());
$db_selected = mysql_select_db($dbname, $link) or die('Nie mozna wybrac bazy: ' . $dbname . ' ' . mysql_error());
mysql_query('SET NAMES \'utf8\' COLLATE \'utf8_general_ci\';',$link);
 
$tables = array(
	'banner' => array( 0 => 'bid', 1 => 'name:alias'),
	'categories' => array( 0 => 'id', 1 => 'title:alias'),
	'content' => array( 0 => 'id', 1 => 'title:alias'),
	'menu' => array( 0 => 'id', 1 => 'name:alias'),
	'sections' => array( 0 => 'id', 1 => 'title:alias'),
	'weblinks' => array( 0 => 'id', 1 => 'title:alias'),
);
 
function clean_alias_string($string)
{
	$map1 = array (
		"\xc4\x84", "\xc5\x81", "\xc4\xbd", "\xc5\x9a",
		"\xc2\xa7", "\xc5\xa0", "\xc5\x9e", "\xc5\xa4",
		"\xc5\xb9", "\xc5\xbd", "\xc5\xbb", "\xc4\x85",
		"\xc5\x82", "\xc4\xbe", "\xc5\x9b", "\xc5\xa1",
		"\xc5\x9f", "\xc5\xa5", "\xc5\xba", "\xc5\xbe",
		"\xc5\xbc", "\xc5\x94", "\xc3\x81", "\xc3\x82",
		"\xc4\x82", "\xc3\x84", "\xc4\xb9", "\xc4\x86",
		"\xc3\x87", "\xc4\x8c", "\xc3\x89", "\xc4\x98",
		"\xc3\x8b", "\xc4\x9a", "\xc3\x8d", "\xc3\x8e",
		"\xc4\x8e", "\xc4\x90", "\xc5\x83", "\xc5\x87",
		"\xc3\x93", "\xc3\x94", "\xc5\x90", "\xc3\x96",
		"\xc3\x97", "\xc5\x98", "\xc5\xae", "\xc3\x9a",
		"\xc5\xb0", "\xc3\x9c", "\xc3\x9d", "\xc5\xa2",
		"\xc3\x9f", "\xc5\x95", "\xc3\xa1", "\xc3\xa2",
		"\xc4\x83", "\xc3\xa4", "\xc4\xba", "\xc4\x87",
		"\xc3\xa7", "\xc4\x8d", "\xc3\xa9", "\xc4\x99",
		"\xc3\xab", "\xc4\x9b", "\xc3\xad", "\xc3\xae",
		"\xc4\x8f", "\xc4\x91", "\xc5\x84", "\xc5\x88",
		"\xc3\xb3", "\xc3\xb4", "\xc5\x91", "\xc3\xb6",
		"\xc5\x99", "\xc5\xaf", "\xc3\xba", "\xc5\xb1",
		"\xc3\xbc", "\xc3\xbd", "\xc5\xa3",
	);
	$map2 = array (
		"\x41", "\x4c", "\x4c", "\x53", "\x53", "\x53",
		"\x53", "\x54", "\x5a", "\x5a", "\x5a", "\x61",
		"\x6c", "\x6c", "\x73", "\x73", "\x73", "\x74",
		"\x7a", "\x7a", "\x7a", "\x52", "\x41", "\x41",
		"\x41", "\x41", "\x4c", "\x43", "\x43", "\x43",
		"\x45", "\x45", "\x45", "\x45", "\x49", "\x49",
		"\x44", "\x44", "\x4e", "\x4e", "\x4f", "\x4f",
		"\x4f", "\x4f", "\x78", "\x52", "\x55", "\x55",
		"\x55", "\x55", "\x59", "\x54", "\x73\x73",
		"\x72", "\x61", "\x61", "\x61", "\x61", "\x6c",
		"\x63", "\x63", "\x63", "\x65", "\x65", "\x65",
		"\x65", "\x69", "\x69", "\x64", "\x64", "\x6e",
		"\x6e", "\x6f", "\x6f", "\x6f", "\x6f", "\x72",
		"\x75", "\x75", "\x75", "\x75", "\x79", "\x74",
	);
	$string = str_replace($map1,$map2,$string);
	$string = strtolower($string);
	$string = preg_replace('#[\\W]{1,}#','-',$string);
	$string = trim($string);
	$string = trim($string,'-');
	$string = trim($string);
	return $string;
}
 
foreach($tables as $key => $value){
	$val=explode(':',$value[1]);
	$get = '`'.$value[0].'`, `'.$val[0].'`';
	$tbl = $prefix.$key;
 
	$result = mysql_query('SELECT '.$get.' FROM `'.$tbl.'`;');
	if (mysql_num_rows($result) != 0) {
		while ($row = mysql_fetch_row($result)) {
			$query = 'UPDATE `'.$tbl.'` SET `'.$val[1].'` = \''.clean_alias_string($row[1]).'\' WHERE `'.$value[0].'` ='.$row[0].';';
			mysql_query($query, $link) or print('<br>Nie mozna wykonac zapytania: ' . $query . ' ' . mysql_error() . '<br>');
		}
	}else{
		echo '<br><strong>Problem z tabela: '.$tbl.' (mozliwe, ze jest pusta)</strong><br>';
	}
 
}
echo 'Koniec - <a href="https://tosiek.pl/">alias updater joomla by tosiek</a>';
unlink(__FILE__);
?>

Przyjazne adresy SEF URL Joomla

Otóż aby przyjazne adresy zaczęły działać należy do pliku .htaccess w głównym folderze dodać (to jest to samo co w pliku htaccess.txt tyle że bez komentarzy) lub zmienić nazwę pliku htaccess.txt na .htacces. Wymaga to modułu mod_rewrite na serwerze.

# @version $Id: htaccess.txt 21064 2011-04-03 22:12:19Z dextercowley $
Options +FollowSymLinks
RewriteEngine On
#RewriteBase /
 
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
RewriteRule .* index.php [F]
 
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
 
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_URI} (/[^.]*|\.(php|html?|feed|pdf|raw))$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

Następnie w panelu administratora przechodzimy do Witryna ⇨Konfiguracja. W zakładce Witryna w sekcji Optymalizacja dla wyszukiwarek zaznaczamy

  • Proste adresy – TAK
  • Korzystaj z mod_rewrite – TAK
  • Adresy z przyrostkiem – wedle uznania; jeśli chcesz aby podstrony miały rozszerzenie .html na końcu to zaznacz na tak jeśli wolisz adresy bez rozszerzeń plików to zaznacz NIE
Konfiguracja przyjazne adresy dla wyszukiwarek Joomla

Konfiguracja przyjaznych adresów oraz polskie znaki w adresach Joomla

Zapisz konfigurację i wyczyść pamięć podręczną.

Polskie znaki w adresie w pasku przeglądarki

Polskie znaki w aliasach Joomla

Widoczne polskie znaki w aliasach Joomla oraz w pasku adresu przeglądarki

Jeśli chcesz aby w pasku adresu w przeglądarce były widoczne polskie znaki i nie chcesz aby polskie znaki były podmieniane na odpowiedniki bez ogonków to musisz zamienić w pliku /libraries/joomla/filter/filteroutput.php funkcję stringURLSafe():

	function stringURLSafe($string)
	{
		//remove any '-' from the string they will be used as concatonater
		$str = str_replace('-', ' ', $string);
 
		$lang =& JFactory::getLanguage();
		$str = $lang->transliterate($str);
 
		// remove any duplicate whitespace, and ensure all characters are alphanumeric
		$str = preg_replace(array('/\s+/','/[^A-Za-z0-9\-]/'), array('-',''), $str);
 
		// lowercase and trim
		$str = trim(strtolower($str));
		return $str;
	}

całą tę funkcję zamień na:

function stringURLSafe($string) {
	$map1 = array(
		"\xc4\x84", "\xc5\x81", "\xc4\xbd", "\xc5\x9a",
		"\xc2\xa7", "\xc5\xa0", "\xc5\x9e", "\xc5\xa4",
		"\xc5\xb9", "\xc5\xbd", "\xc5\xbb", "\xc4\x85",
		"\xc5\x82", "\xc4\xbe", "\xc5\x9b", "\xc5\xa1",
		"\xc5\x9f", "\xc5\xa5", "\xc5\xba", "\xc5\xbe",
		"\xc5\xbc", "\xc5\x94", "\xc3\x81", "\xc3\x82",
		"\xc4\x82", "\xc3\x84", "\xc4\xb9", "\xc4\x86",
		"\xc3\x87", "\xc4\x8c", "\xc3\x89", "\xc4\x98",
		"\xc3\x8b", "\xc4\x9a", "\xc3\x8d", "\xc3\x8e",
		"\xc4\x8e", "\xc4\x90", "\xc5\x83", "\xc5\x87",
		"\xc3\x93", "\xc3\x94", "\xc5\x90", "\xc3\x96",
		"\xc3\x97", "\xc5\x98", "\xc5\xae", "\xc3\x9a",
		"\xc5\xb0", "\xc3\x9c", "\xc3\x9d", "\xc5\xa2",
		"\xc3\x9f", "\xc5\x95", "\xc3\xa1", "\xc3\xa2",
		"\xc4\x83", "\xc3\xa4", "\xc4\xba", "\xc4\x87",
		"\xc3\xa7", "\xc4\x8d", "\xc3\xa9", "\xc4\x99",
		"\xc3\xab", "\xc4\x9b", "\xc3\xad", "\xc3\xae",
		"\xc4\x8f", "\xc4\x91", "\xc5\x84", "\xc5\x88",
		"\xc3\xb3", "\xc3\xb4", "\xc5\x91", "\xc3\xb6",
		"\xc5\x99", "\xc5\xaf", "\xc3\xba", "\xc5\xb1",
		"\xc3\xbc", "\xc3\xbd", "\xc5\xa3",
	);
	$string = mb_strtolower($string, 'UTF-8');
	$string = preg_replace('#[^\\w' . implode('', $map1) . ']{1,}#', '-', $string);
	$string = trim($string);
	$string = trim($string,'-');
	$string = trim($string);
	return $string;
}
Polskie znaki w pasku adresu Joomla

Widoczne polskie znaki w pasku adresu w przeglądarce w adresie Joomla

Od tej pory aliasy będą zawierać polskie znaki w czystej postaci. Mogą wystąpić problemy w starszych przeglądarkach oraz na niektórych serwerach lecz ustawienie setlocale() powinno pomóc. Z adresowaniem i linkowaniem nie powinno być problemów ze względu na to, że po skopiowaniu takiego adresu zostaje on zakodowany jako część adresu URL (czyli zawiera procenty % i wartości dla poszczególnych znaków) i po wklejeniu go gdzieś zostanie wklejony w zakodowanej formie.

1 Comment

  1. joomcode.net

    07.07.2011 at 16:18

    Świetny tutek, gratuluję.

Dodaj komentarz