Pull to refresh

Построение sitemap.xml для мультиязычного сайта из json

Как-то довелось столкнуться с довольно простой, но интересной задачкой. Написать функционал на PHP, который для всего сайта будет формировать sitemap.xml для поисковых систем из json данных.

Исходные данные следующие:
  • сайт, который поддерживает многоязычность;
  • sitemap у каждой локализации может быть уникальным;
  • для каждого языка структура сайта описана в отдельном файле в формате json;
  • файлов может быть больше или равно одному. Называются они {lang}.sitemap.


Пример файла для русского языка:
ru.sitemap
{
    "first": [
        "a1",
        "a2",
        "a3"
    ],
    "second": {
        "b1": [
            "c1",
            "c2",
            "c3"
        ],
        "b2": [
            "d1",
            "d2",
            "d3"
        ]
    }
}


На базе данной структуры url'ы сайта должный выглядеть так:
site.ru/ru/
site.ru/ru/first/
site.ru/ru/first/a1.html
site.ru/ru/first/a2.html
site.ru/ru/first/a3.html

Настройки времени и приоритет для каждого элемента в sitemap.xml выставляется произвольно.

Пример как решить такую задачу для того уровня вложенности, который приведен выше.
<?
function getJsonMap($mapArray,$part,$lastPart=null)
{
    GLOBAL $siteAddr, $mapPath,$lang,$priority;
    if ($lastPart) {
        $lastPart .= "/".$part;
    } else {
        $lastPart .= $part;
    }
    $link = $siteAddr."/".$lang."/".$lastPart."/";
    $mapContent ='<url> <loc>'.$link.'</loc> <priority>'.$priority.'</priority> </url>';
    fwrite($mapPath, $mapContent);
    foreach($mapArray as $nextPart => $value) {
        if (is_array($value)) {
            getJsonMap($value,$nextPart,$lastPart);
        } else {
            if (is_object($value)) {
                foreach($value as $objectPart => $nextValue) {
                    $objectNextPart = $lastPart."/".$nextPart;
                    getJsonMap($nextValue,$objectPart,$objectNextPart);
                }
            } else {
                $link = $siteAddr."/".$lang."/".$lastPart."/".$value.".html";
                $mapContent ='<url> <loc>'.$link.'</loc> <priority>'.$priority.'</priority> </url>';
                fwrite($mapPath, $mapContent);
            }
        }
    }
}
 
function getLanguage($jsonMap)
{
    $lang = explode(".",$jsonMap);
    return ($lang[0]);
}
 
$siteAddr = "http://site.ru";
$priority = "0.8";
$mapPath = fopen('sitemap.xml', 'w');
$header = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xsi:schemaLocation="http://www.sitemap.org/schemas/sitemap/0.9 http://www.sitemap.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemap.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
$mapContent = '<url> <loc>'.$siteAddr.'/</loc> <priority>1.0</priority> </url>';
fwrite($mapPath, $header.$mapContent);
echo "Доступные языковые локализации<br>";
foreach (glob("*.sitemap.json") as $jsonMap) {
    echo $jsonMap."<br>";
    $lang = getLanguage($jsonMap);
    $link = $siteAddr."/".$lang."/";
    $mapContent ='<url> <loc>'.$link.'</loc> <priority>'.$priority.'</priority> </url>';
    fwrite($mapPath, $mapContent);
    $getJsonMap = json_decode(file_get_contents($jsonMap));
    foreach($getJsonMap as $part => $value) {
        getJsonMap($value,$part);
    }
}
$mapContent = "</urlset>";
fwrite($mapPath, $mapContent);
fclose($mapPath);
echo "Файл sitemap.xml успешно создан";
?>


В результате получаем sitemap.xml следующего вида:

http://site.ru/
1.0
 
http://site.ru/ru/
0.8
 
http://site.ru/ru/first/
0.8
 
http://site.ru/ru/first/a1.html
0.8
 
http://site.ru/ru/first/a2.html
0.8
 
http://site.ru/ru/first/a3.html
0.8
 
http://site.ru/ru/second/
0.8
 
http://site.ru/ru/second/b1/
0.8
 
http://site.ru/ru/second/b1/c1.html
0.8
 
http://site.ru/ru/second/b1/c2.html
0.8
 
http://site.ru/ru/second/b1/c3.html
0.8
 
http://site.ru/ru/second/b2/
0.8
 
http://site.ru/ru/second/b2/d1.html
0.8
 
http://site.ru/ru/second/b2/d2.html
0.8
 
http://site.ru/ru/second/b2/d3.html
0.8
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.