Вообщем решил собрать по сусекам все что у меня есть полезного и нужного для СЕО оптимизации и объединить в один пакет.
Что мы умеем?
- Проставлять alt длля картинок согласно шаблону, с порядковым номеро
- Проставлять title для ссылок согласно содержанию, а если там пустота — ставить свой текст по шаблону, также с порядковым номером
- Вытягивать код в одну строку (спасибо Agel_Nash), но оставлять нетронутым тэг pre (лично я не пользовался режением Евгения, именно из-за этого)
- Убирать внешние ссылки, но оставлять возможность перехода по ним (не забываем в роботе прописать Disallow: /exit.php)
- Убирать циклиечские ссылки (т.е.ссылки на самих себя) — где-то слышал, что это не зер гуд
- Формировать ключевики из тэгов h1-h6,b,i,strong и докидывать получившиеся к основным
В принципе и не так много, но весьма полезно.
Минусы решения:
- Т.к. идет постобработка, то увеличивается время генерации страницы. Хотя я разницы особо и не заметил, ибо там простые, по-сути, математические действия
Плюсы:
- Установил и оно работает
- Работает как со старыми, так и с новыми документами, не нужно ничего пересохранять
- Смотрит не только в поле контента, а по всей странице. Поэтому дополняет «чанки, шаблоны и прочие телевизоры)»
- Делает MODX реально лучшим движком для СЕО)
Установка:
Качаем отсель библиотеку simple_html_dom и кидаеи ее в папочку /assets/lib/ (нам нужен тольк один файлик — simple_html_dom.php), все остальное примеры и доки.
Создаем плагин, называем SEOPack, ставим события OnWebPagePrerender, OnPageNotFound
Вставляем нижеследующий код:
$error_page = 'exit.php'; //Уникальное название страницы, куда первоначально будем делать редирект при внешнем ресурсе
$e =&$modx->Event;
function compress_html($compress)
{
// Подсмотренно у Agel Nash
$compress = str_replace("\n", '', $compress);
$compress = str_replace("\s", '', $compress);
$compress = str_replace("\r", '', $compress);
$compress = str_replace("\t", '', $compress);
$compress = preg_replace('/(?:(?<=\>)|(?<=\/\>))\s+(?=\<\/?)/', '', $compress);
$compress = preg_replace('/[\t\r]\s+/', ' ', $compress);
$compress = preg_replace('/<!(--)([^\[|\|])^(<!-->.*<!--.*-->)/', '', $compress);
$compress = preg_replace('/\/\*.*?\*\//', '', $compress);
return preg_replace("#\\s+#ism"," ",$compress);
}
if ($e->name=='OnWebPagePrerender')
{
$content = $modx->Event->params['documentOutput'];
require_once MODX_BASE_PATH.'assets/lib/simple_html_dom.php';
$html = new simple_html_dom();
$html->load($content, false, null, -1, -1, true, true, DEFAULT_TARGET_CHARSET, false);
$title = $html->find('title',0);
$metaTitle = str_replace("'","'",$title->plaintext); // Чтобы не искать потом - заголовок страницы
$imagealt = $metaTitle.'. Картинка '; //в конце подставляется порядковый номер начиная с 1
$atitle = $metaTitle.' Ссылка '; //в конце подставляется порядковый номер начиная с 1
//Проставляем тэг title для ссылок
$links = $html->find("a");
$ln = 1;
foreach ($links as $key => $link)
{
if (!$link->title)
{
if ($link->plaintext)
{
$t = str_replace('"',"'",trim(mb_substr($link->plaintext,0,50)));
if (strlen($t)<10)
{
$link->title = $atitle.' '.$ln;
$ln++;
}
else $link->title = $t;
}
else
{
$link->title = $atitle.' '.$ln;
$ln++;
}
}
}
//Убираем циклические ссылки
$url = substr($_SERVER['REQUEST_URI'], 1);
if ($url)
{
$cu = $html->find("a[href='".$url."']");
foreach($cu as $u) $u->href = null;
}
//Закрываем внешние ссылки
$outlink = $html->find("a[href^=http]");
foreach($outlink as $ou) if (strpos($ou->href, MODX_SITE_URL)===false) $ou->href = MODX_SITE_URL.''.$error_page.'?url='.$ou->href;
//Проставляем тэг alt для картинок
$imgs = $html->find("img");
$ln = 1;
foreach ($imgs as $key => $img)
{
if (!$img->alt)
{
$img->alt = $imagealt.' '.$ln;
$ln++;
}
}
//Генерим ключевики по тэгам
$mk = $html->find('meta[name=keywords]',0);
if (count($mk))
{
$min = isset($min) ? $min : 4; //минимальное количество символов в слове при выборке
$limit = isset($limit) ? $limit : 20; // сколько слов выводить
$keywords = [];
$keyws = $html->find("h1,h2,h3,h4,h5,h6,b,i,strong");
foreach($keyws as $keyw) $keywords[]=$keyw->plaintext;
$str = implode(',',$keywords);
$str = strip_tags($str);
$str2 = preg_replace('/[^a-zA-Zа-яА-Я0-9\s]/ui', ' ',$str );
$str2 = str_replace(' ',' ',$str2);
$str2 = str_replace(PHP_EOL,' ',$str2);
$arr = explode(' ',$str2);
foreach($arr as $key=>$val) if ($val) $arr[$key] = mb_strtolower(trim($val),'utf-8');
//Выбираем наиболее часто встречающиеся
$array_words = array_count_values($arr);
arsort($array_words);
$out = array();
foreach($array_words as $word => $val)
{
if (mb_strlen($word,'utf-8')>=$min) $out[]=$word;
if (count($out)==$limit) break;
}
$mk->content = mb_substr($mk->content.','.implode(',',$out), 0, 200);
}
// Хак для того, чтобы не сжимать тэг <pre>
$pre = $html->find("pre");
if (count($pre))
{
$arr_pre = [];
foreach ($pre as $p) $arr_pre[] = $p->outertext;
}
$content = $html->save();
$html->clear();
$content = compress_html($content); //Вытягиваем в 1-у строку
// Хак для того, чтобы не сжимать тэг <pre>
if (count($pre))
{
preg_match_all('~<pre(.*?)pre>~s', $content, $matches);
foreach ($matches[0] as $key => $pre) $content = str_replace($pre,$arr_pre[$key],$content);
}
$modx->Event->output($content);
}
if ($e->name=='OnPageNotFound')
{
$q = $modx->db->escape($_REQUEST['q']);
if (isset($_GET['url']) && (!empty($_GET['url'])) && ($q==$error_page))
{
$url = $_GET['url'];
if (!preg_match('#(https?|ftp)://\S+[^\s.,>)\];\'\"!?]#i',$url))
{
exit ("<p>Неверный формат запроса! Проверьте URL!</p>");
}
header("Location:$url");
exit();
}
}
Наслаждаемся результатом.
Да. Проверял уже на обновленных движках; на старых, у меня че-та не хотел срабатывать вывод на плагине OnWebPagePrerender, решил тогда echo $content; exit(); Ну это так, на всякий случай. Ну и если будут желающие задонатить, то как бы я не против)
Ну а так, предоставляю как есть. Будут всплывать баги — будем править. Если кому-то нужна какая-то тонка настройка — обращайтесь в личку.
Не реклама, но можете глянуть плагин в действии на моем сайте liber.pro
lusen 18.03.2017 18:43 #
Алексей Либер 22.03.2017 20:10 #
Dmi3yy 22.03.2017 20:20 #
Вараника 25.03.2017 11:19 #
Андрей 28.03.2017 16:01 #
Плагин отключил сайт заработал
Алексей Либер 28.03.2017 16:04 #
Это связанно с различием объявление массива на разных версиях php
Андрей 28.03.2017 16:06 #
Алексей Либер 28.03.2017 16:09 #
Андрей 28.03.2017 16:26 #
Алексей Либер 28.03.2017 16:28 #
Если нужна помощь — пишите в личку, посмотрим чем можно помочь. Но тока не сегодня, ща аврал)
Андрей 28.03.2017 16:30 #
Алексей Либер 28.03.2017 16:31 #