Базируется на той же идее, что и первая версия (подмена ссылок на лету, в буфере сформированной страницы).
Отличия:
- Стал оптимальнее (быстрее), т.к. я за три года узнал много нового.
- Теперь не только автоматический.
Т.е. можно нажатием кнопки в админке сгенерировать ЧПУ-ссылки по категориям-товарам-страницам-новостям,
но можно и вручную задавать каждому элементу ЧПУ-ссылку. А также удалять ее.
- Работает "смешанно", т.е. если у элемента есть ЧПУ-ссылка, то запрос старой ссылки (без ЧПУ) вызовет редирект-301 на ЧПУ-ссылку, а если нет ЧПУ-ссылки, то обычным загрузится страница этого элемента.
- Можно задавать в админке стиль ЧПУ.
Т.е. "хлебные крошки" или "только последняя категория", добавлять ЧПУ-категории к ЧПУ-товара или нет, добавлять к ЧПУ-товара/страницы/новости его ID или нет.
- Можно задавать в админке набор статических редиректов-301. Например, с /aaaaa.html на /bbbbb/.
- Можно задавать в админке подмены для редиректов-301. Например, задав &aaa -> bbb получим редирект-301 с подменой всех вхождений aaa на bbb.
- генерация ЧПУ-ссылок в админке делается "порциями" путем AJAX-запросов. Размер порции задается там же.
Сделано на всякий случай, мало ли кому не хватит разрешенного времени выполнения скрипта на оЧПУшивание всех 100500 товаров за один заход .
- При включении "АвтоЧПУ" генерация ЧПУ-ссылок для товаров их не имеющих происходит автоматически.
2.JPG 23.39К 224 Количество загрузок:
3.JPG 23.03К 175 Количество загрузок:
4.JPG 11.14К 146 Количество загрузок:
5.JPG 14.65К 140 Количество загрузок:
6.JPG 17.46К 155 Количество загрузок:
Установка:
----------
1. переименовываем index.php в index_old.php
2. копируем файлы
index.php -> корень сайта
sitemap.php -> корень сайта
cpu_functions.php -> core/functions/
addon.php -> core/includes/admin/
modules_friendly_cpu.php -> core/includes/admin/sub/
modules_friendly_cpu.tpl.html -> core/tpl/admin/
3. в файле default.tpl.html перед строкой
<div class="marg"><a href="{$smarty.const.ADMIN_FILE}?dpt=modules&sub=yandex">{$smarty.const.ADMIN_STRING_YANDEX}</a></div>
вставляем
{* BEGIN SimpleFriendlyURL *}
<div class="marg"><a href="{$smarty.const.ADMIN_FILE}?dpt=modules&sub=friendly_cpu">Модуль ЧПУ</a></div>
{* END SimpleFriendlyURL *}
4. в файле core/tpl/admin/menu.tpl.html перед строкой
<table class="adn topj"><tr><td><img src="data/admin/drs.gif" alt=""></td><td width="100%"><a href="{$smarty.const.ADMIN_FILE}?dpt=modules&sub=yandex">{$smarty.const.ADMIN_STRING_YANDEX}</a></td></tr></table>
вставляем
{* BEGIN SimpleFriendlyURL *}
<table class="adn topj"><tr><td><img src="data/admin/drs.gif" alt=""></td><td width="100%"><a href="{$smarty.const.ADMIN_FILE}?dpt=modules&sub=friendly_cpu">Модуль ЧПУ</a></td></tr></table>
{* END SimpleFriendlyURL *}
5. в файле custord_aux_pages.tpl.html
5.1 перед строками
<tr class="linsz">
<td align="left" style="padding-top: 0;"><span class="titlecol2">{$smarty.const.ADMIN_PRODUCT_TITLE_PAGE}</span></td>
вставляем
{* BEGIN SimpleFriendlyURL *}
<tr class="linsz"><td style="padding-top: 0;"><span class="titlecol2">ЧПУ</span></td></tr>
<tr>
<td>
<input name="cpu" type="text" value='{$cpu}' style="width: 500px;" class="textp" placeholder="/page-cpu-url.html">
<input type="button" value="транслит" onclick="cpu_translit(2);">
<input type="hidden" name="cpu_ID" value="{$cpu_ID}">
</td>
</tr>
<tr><td class="se5"></td></tr>
{* END SimpleFriendlyURL *}
5.2 вместо строки
<td align="left"><a href="{if $smarty.const.CONF_MOD_REWRITE eq 1}page_{$aux_pages[i].aux_page_ID}.html">{$aux_pages[i].aux_page_name}{else}index.php?show_aux_page={$aux_pages[i].aux_page_ID}">{$aux_pages[i].aux_page_name}{/if}</a></td>
вставляем
{* BEGIN SimpleFriendlyURL *}
{*<td align="left"><a href="{if $smarty.const.CONF_MOD_REWRITE eq 1}page_{$aux_pages[i].aux_page_ID}.html">{$aux_pages[i].aux_page_name}{else}index.php?show_aux_page={$aux_pages[i].aux_page_ID}">{$aux_pages[i].aux_page_name}{/if}</a></td>*}
<td align="left"><a href="{if $smarty.const.CONF_MOD_REWRITE eq 1}{if $aux_pages[i].cpu}{$aux_pages[i].cpu}{else}page_{$aux_pages[i].aux_page_ID}.html">{$aux_pages[i].aux_page_name}{/if}{else}index.php?show_aux_page={$aux_pages[i].aux_page_ID}">{$aux_pages[i].aux_page_name}{/if}</a></td>
{* END SimpleFriendlyURL *}
6. в файле modules_news.tpl.html
после строки
<tr class="lins"><td align="left">{$smarty.const.ADMIN_NEWS_TITLE}: <input type=text name='title' value='{if $edit_news}{$edit_news.title}{else}{$title}{/if}' style="width: 440px;" class="textp"> {$smarty.const.ADMIN_CURRENT_DATE}: <input type=text name='add_date' value="{if $edit_news}{$edit_news.add_date}{else}{$current_date}{/if}" style="width: 86px;" class="textp"></td></tr>
вставляем
{* BEGIN SimpleFriendlyURL *}
<tr class="lins"><td>
ЧПУ:
<input type="text" name="cpu" value="{$cpu}" style="width: 440px;" class="textp" placeholder="/news-cpu-url.html">
<input type="button" value="транслит" onclick="cpu_translit(3);">
<input type="hidden" name="cpu_ID" value="{$cpu_ID}">
</td></tr>
{* END SimpleFriendlyURL *}
7. в файле category_functions.php в функции catDeleteCategory
перед строкой
_deleteSubCategories( $categoryID );
вставляем
# BEGIN SimpleFriendlyURL
cpu_category_delete($categoryID);
# END SimpleFriendlyURL
8. в файле news_function.php в функции newsDeleteNews
в самый конец вставляем
# BEGIN SimpleFriendlyURL
cpu_delete($newsid,3);
# END SimpleFriendlyURL
9. в файле product_functions.php
9.1. в функцию UpdateProduct в самое начало
вставляем
# BEGIN SimpleFriendlyURL
cpu_update($_POST["cpu"],$productID,1);
# END SimpleFriendlyURL
9.2. в функцию AddProduct в самый конец (перед return $insert_id;)
вставляем
# BEGIN SimpleFriendlyURL
cpu_update($_POST["cpu"],$insert_id,1);
# END SimpleFriendlyURL
9.3. в функцию DeleteProduct
перед
return true;
вставляем
# BEGIN SimpleFriendlyURL
cpu_delete($productID,1);
# END SimpleFriendlyURL
10. в файле aux_pages_functions.php
10.1. в функции auxpgGetAllPageAttributes
строку
$q = db_query("select aux_page_ID, aux_page_name, aux_page_text_type from ".AUX_PAGES_TABLE);
заменяем на
# BEGIN SimpleFriendlyURL
#$q = db_query("select aux_page_ID, aux_page_name, aux_page_text_type from ".AUX_PAGES_TABLE);
$q = db_query("SELECT aux_page_ID, aux_page_name, aux_page_text_type, cpu FROM ".AUX_PAGES_TABLE.
" LEFT JOIN ".DB_PRFX."cpu ON (type=2 AND aux_page_ID=ID)");
# END SimpleFriendlyURL
10.2. в функции auxpgDeleteAuxPage
в самый конец вставляем
# BEGIN SimpleFriendlyURL
cpu_delete($aux_page_ID,2);
# END SimpleFriendlyURL
11. в файле custord_aux_pages.php
11.1. перед строкой
auxpgUpdateAuxPage( $_GET["edit"], $_POST["aux_page_name"],
вставляем
# BEGIN SimpleFriendlyURL
cpu_update($_POST["cpu"],$_GET["edit"],2);
# END SimpleFriendlyURL
11.2. перед строкой
$aux_page = auxpgGetAuxPage( $_GET["edit"] );
вставляем
# BEGIN SimpleFriendlyURL
$smarty->assign( "cpu",($row = db_fetch_assoc(db_query("SELECT cpu FROM ".DB_PRFX."cpu WHERE type=2 AND ID=".$_GET["edit"]." LIMIT 1")))?$row['cpu']:'');
$smarty->assign( "cpu_ID",(CONF_FRIENDLY_CPU_PRODID2 && isset($_GET["edit"]))?('-'.$_GET["edit"]):'');
# END SimpleFriendlyURL
12. в файле modules_news.php
12.1. перед строкой
$edit_news = newsGetNewsToEdit($_GET["edit"]);
вставляем
# BEGIN SimpleFriendlyURL
$smarty->assign( "cpu",($row = db_fetch_assoc(db_query("SELECT cpu FROM ".DB_PRFX."cpu WHERE type=3 AND ID=".$_GET["edit"]." LIMIT 1")))?$row['cpu']:'');
$smarty->assign( "cpu_ID",(CONF_FRIENDLY_CPU_PRODID3 && isset($_GET["edit"]))?('-'.$_GET["edit"]):'');
# END SimpleFriendlyURL
12.2. перед строкой
newsUpdateNews($_POST["add_date"], $_POST["title"], $_POST["textToPrePublication"], $_POST["textToPublication"], $_POST["textToMail"], $_POST["edit_news_id"] );
вставляем
# BEGIN SimpleFriendlyURL
cpu_update($_POST["cpu"],$_POST["edit_news_id"],3);
# END SimpleFriendlyURL
13. в файле modules.php перед строкой
array("id"=>"yandex", "name"=>"Яндекс.Маркет" )
вставляем
# BEGIN SimpleFriendlyURL
array("id"=>"friendly_cpu", "name"=>"Модуль ЧПУ"),
# END SimpleFriendlyURL
14. в файле admin.php
14.1. после строк (строк!)
$pid = (int)$_POST["must_delete"];
}
вставляем
# BEGIN SimpleFriendlyURL
cpu_update($_POST["cpu"],$pid,0);
# END SimpleFriendlyURL
14.2. после строки
$row = catGetCategoryById($_GET["categoryID"]);
вставляем
# BEGIN SimpleFriendlyURL
$row['cpu']= ($row1 = db_fetch_assoc(db_query("SELECT cpu FROM ".DB_PRFX."cpu WHERE type=0 AND ID=".$row['categoryID']." LIMIT 1")))?$row1['cpu']:'';
$row['cpu_parent'] = (CONF_FRIENDLY_CPU_CATCAT?cpu_cats($row['parent']):'').'/';
# END SimpleFriendlyURL
14.3. перед строкой
$show_subcategories_products = 1;
вставляем
# BEGIN SimpleFriendlyURL
$row['cpu_parent'] = (CONF_FRIENDLY_CPU_CATCAT?cpu_cats($parent):'').'/';
# END SimpleFriendlyURL
14.4. после строк (искать удобно по ADMIN_SORT_ORDER, это единственное вхождение)
echo ADMIN_SORT_ORDER;
?>: <input type="text" name="sort_order" value="<?php
echo $sort_order
?>" class="textp" size="10"></td></tr>
вставляем
<!-- BEGIN SimpleFriendlyURL -->
<tr>
<td colspan="2">
ЧПУ:
<input type="text" name="cpu" value="<?php echo $row["cpu"];?>" style="width: 590px;" class="textp" placeholder="/category-cpu-url/">
<input type="button" value="транслит" onclick="cpu_translit(0);">
<input type="hidden" name="cpu_parent" value="<?php echo $row["cpu_parent"];?>">
</td>
</tr>
<!-- END SimpleFriendlyURL -->
14.5. после строки
$product = GetProduct($_GET["productID"]);
вставляем
# BEGIN SimpleFriendlyURL
$product['cpu'] = ($row = db_fetch_assoc(db_query("SELECT cpu FROM ".DB_PRFX."cpu WHERE type=1 AND ID=".$product['productID']." LIMIT 1")))?$row['cpu']:'';
# END SimpleFriendlyURL
14.6. после строки
$appended_categories = catGetAppendedCategoriesToProduct($_GET["productID"]);
вставляем
# BEGIN SimpleFriendlyURL
if(CONF_FRIENDLY_CPU_CATPROD)
if(CONF_FRIENDLY_CPU_CATCAT)
$row['cpu_parent'] = cpu_cats($product['categoryID']).'/';
else
{
$nocatcat = catGetCategoryById($product['categoryID']);
$row['cpu_parent'] = '/'.cpu_translit($nocatcat['name']).'/';
}
else $row['cpu_parent'] = '/';
$row['cpu_ID'] = (CONF_FRIENDLY_CPU_PRODID && isset($product['productID']))?('-'.$product['productID']):'';
# END SimpleFriendlyURL
14.7. после строк
echo $product["name"];
?>" style="width: 590px;" class="textp"></td></tr>
вставляем
<!-- BEGIN SimpleFriendlyURL -->
<tr class="lins"><td>
ЧПУ:
<input type="text" name="cpu" value="<?php echo $product["cpu"];?>" style="width: 590px;" class="textp" placeholder="/product-cpu-url.html">
<input type="button" value="транслит" onclick="cpu_translit(1);">
<input type="hidden" name="cpu_parent" value="<?php echo $row["cpu_parent"];?>">
<input type="hidden" name="cpu_ID" value="<?php echo $row["cpu_ID"];?>">
</td></tr>
<!-- END SimpleFriendlyURL -->
15. в файле index_old.php заменяем
include("core/config/init.php");
include("core/includes/database/mysql.php");
на
# BEGIN SimpleFriendlyURL
#include("core/config/init.php");
#include("core/includes/database/mysql.php");
require_once "core/config/init.php";
require_once "core/includes/database/mysql.php";
# END SimpleFriendlyURL
16. в файл admin.js куда нибудь (например, в самый конец) вставляем
// BEGIN SimpleFriendlyURL function admin_translit(str){ // коррекция для старого ЧПУ. Для сохранения тех же ссылок, что и в старом закомментровать/расскомментировать соответствующие строки. var old = new Array('а','б','в','г','д','е','ё' ,'ж' ,'з','ы','и','й','к','л','м','н','о','п','р','с','т','у','ф','х','ц', 'ч' ,'ш' ,'щ' ,'ъ','ь','э','ю' ,'я' ,'ї' ,'і','є' ) var trl = new Array('a','b','v','g','d','e','yo','zh','z','y','i','y','k','l','m','n','o','p','r','s','t','u','f','h','ts','ch','sh','sch','' ,'' ,'e','yu','ya','yi','i','ye') // var old = new Array('А','Б','В','Г','Д','Е','Ж','З','И','Й','К','Л','М','Н','О','П','Р','С','Т','У','Ф','Х','Ц' ,'Ч' ,'Ш' ,'Щ' ,'Ъ','Ы' ,'Ь','Э','Ю' ,'Я' ,'а','б','в','г','д','е','ж','з','и','й','к','л','м','н','о','п','р','с','т','у','ф','х','ц' ,'ч' ,'ш' ,'щ' ,'ъ','ы' ,'ь','э','ю' ,'я' ,'ё','Ё','є','Є','І','і','Ї','ї',' ','_','\\+','№') // var trl = new Array('a','b','v','g','d','e','j','z','i','y','k','l','m','n','o','p','r','s','t','u','f','h','ts','ch','sh','sch','' ,'yi','' ,'e','yu','ya','a','b','v','g','d','e','j','z','i','y','k','l','m','n','o','p','r','s','t','u','f','h','ts','ch','sh','sch','' ,'yi','' ,'e','yu','ya','e','e','e','e','i','i','i','i','-','-','-' ,'N') for(i=0;i<old.length;i++){ y = eval('/'+old[i]+'/gi'); str = str.replace(y,trl[i]); } return str.replace(/[^a-zA-Z0-9]/g,'-'); // return str.replace(/[^a-zA-Z0-9\-]/g,''); } function cpu_translit(type){ if (type == 2) var form = document.getElementById('formaxp'); else var form = document.getElementById('MainForm'); if(form.cpu.value.length == 0) { if (type == 0) form.cpu.value = form.cpu_parent.value+admin_translit(form.name.value)+'/'; if (type == 1) form.cpu.value = form.cpu_parent.value+admin_translit(form.name.value)+form.cpu_ID.value+'.html'; if (type == 2) form.cpu.value = '/'+admin_translit(form.aux_page_name.value)+form.cpu_ID.value+'.html'; if (type == 3) form.cpu.value = '/news/'+admin_translit(form.title.value)+form.cpu_ID.value+'.html'; } else alert('ЧПУ уже заполнен (поле не пустое)'); } // END SimpleFriendlyURL
17. в файле data/[шаблон]/user.js все index.php заменяем на /index.php
18. вносим изменения в файл .htaccess аналогично находящемуся в архиве или просто переписываем его поверх.
19. в файл robots.txt добавляем строку
Sitemap: http://ваш-сайт/sitemap.xml
------------------------------------------
Дополнения:
1. Чтобы создались таблицы, нужные для работы ЧПУ надо хотя бы раз зайти в админке в "Модуль ЧПУ".
2. Если не работает, а в логах видим ошибку "Call to undefined function xescsql() ...", то смотрим, в каком файле она происходит и в какой строке.
Обычно это mysql.php или error_handler.php.
Заменяем в этой строке xEscSQL(ToText($out)) на mysql_real_escape_string(htmlspecialchars($out, ENT_QUOTES)) - это ровно то же самое, но без использования внешних функций.
3. если где-то в других модулях прописаны "относительные" пути к файлам, то придется их переделать в "абсолютные", дописав в начале "/" либо внеся соответствуюшие замены в index.php. Для встречающихся в самой CMS и для распространенного модуля "Статьи" это в index.php уже сделано. В некоторых случаях подмена в index.php может не помочь, так что исправление в самом модуле более надежно.
4. в .htaccess есть строка "php_value output_buffering 0", она выключает буферизацию. Частенько хостер запрещает изменять эту настройку, а без нее ЧПУ не работает.
Cоздайте в корне сайта файл info.php
<?php phpinfo(); ?>и выполните его - http://ваш-сайт/info.php - Вы увидите кучу информации, в которой Вас интересует тот самый output_buffering, он должен быть 0 или Off. Если там, например, 4096, то надо обращаться к хостеру.
5. В случае, когда в .htaccess параметр RewriteBase не равен "/" (например, написано "RewriteBase shop") впишите этот параметр в index.php в константу REWRITE_BASE
6.