RedirectMatch古い製品のURL(IDなし)を基本的な(IDを使用する)構造の新しいURLに

May 08 2019

PrestaShop1.7.5のインストールで問題が発生しています。

約2週間前、PrestaShopバージョン(1.7.4から1.7.5)をアップグレードしようとしました。残念ながら、1つの重要なモジュールが機能しなくなりました(ディスパッチャのオーバーライドが古くなっています)。このモジュールは、次のように、URLにIDがないSEO対応のURLを生成します。domain/{category}/{rewrite}

ロールバックを行わないことを好み、2つのオプションを検討しています。

オプション1:すべての古い製品のURLを新しいURLにリダイレクトする

古いURL形式: domain/{category}/{rewrite}

新しいURL形式: domain/{parent-category}/{sub-category}/{ID}-{ID_product_attribute}-{rewrite}

オプション2:すべての404をsearchcontrollerにリダイレクトします

URLのキーワードを使用することで、これを実現するために、パーツ{category}&を使用できます。{rewrite}

私はネット上で見つけた次のような小さなコードをたくさん試しました:

RewriteRule ^search/?$ / [R=301,L] RewriteRule ^search/([^/]+)/?$ /search/$1/1/ [R=301,L] RewriteRule ^search/([^/]+)/([0-9]+)/?$ search.php?q=$1&category=web&d=$2 [NC,L]

マニュアルを読みました https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html 単純なページを別のページにリダイレクトする方法を理解しています...しかし、行き詰まります...

これは現在の私の.htaccesファイルです(prestashopによって生成されます):


# ~~start~~ Do not remove this comment, Prestashop will keep automatically the code outside this comment when .htaccess will be generated again
# .htaccess automaticaly generated by PrestaShop e-commerce open-source solution
# http://www.prestashop.com - http://www.prestashop.com/forums

<IfModule mod_rewrite.c>
<IfModule mod_env.c>
SetEnv HTTP_MOD_REWRITE On
</IfModule>

RewriteEngine on

#Domain: domain.be
RewriteRule . - [E=REWRITEBASE:/]
RewriteRule ^api$ api/ [L] RewriteRule ^api/(.*)$ %{ENV:REWRITEBASE}webservice/dispatcher.php?url=$1 [QSA,L] # Images RewriteCond %{HTTP_HOST} ^domain.be$
RewriteRule ^([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$1$2$3.jpg [L] RewriteCond %{HTTP_HOST} ^domain.be$
RewriteRule ^([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$1$2$3$4.jpg [L] RewriteCond %{HTTP_HOST} ^domain.be$
RewriteRule ^([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$1$2$3$4$5.jpg [L] RewriteCond %{HTTP_HOST} ^domain.be$
RewriteRule ^([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$1$2$3$4$5$6.jpg [L] RewriteCond %{HTTP_HOST} ^domain.be$
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.jpg [L] RewriteCond %{HTTP_HOST} ^domain.be$
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.jpg [L] RewriteCond %{HTTP_HOST} ^domain.be$
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.jpg [L] RewriteCond %{HTTP_HOST} ^domain.be$
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9$10.jpg [L] RewriteCond %{HTTP_HOST} ^domain.be$
RewriteRule ^c/([0-9]+)(\-[\.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/c/$1$2$3.jpg [L]
RewriteCond %{HTTP_HOST} ^domain.be$ RewriteRule ^c/([a-zA-Z_-]+)(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/c/$1$2.jpg [L]
# AlphaImageLoader for IE and fancybox
RewriteRule ^images_ie/?([^/]+)\.(jpe?g|png|gif)$ js/jquery/plugins/fancybox/images/$1.$2 [L] # Dispatcher RewriteCond %{REQUEST_FILENAME} -s [OR] RewriteCond %{REQUEST_FILENAME} -l [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ %{ENV:REWRITEBASE}index.php [NC,L] </IfModule> AddType application/vnd.ms-fontobject .eot AddType font/ttf .ttf AddType font/otf .otf AddType application/font-woff .woff AddType font/woff2 .woff2 <IfModule mod_headers.c> <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|svg)$">
        Header set Access-Control-Allow-Origin "*"
    </FilesMatch>
</IfModule>

<IfModule mod_expires.c>
    ExpiresActive On
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType text/css "access plus 1 week"
    ExpiresByType text/javascript "access plus 1 week"
    ExpiresByType application/javascript "access plus 1 week"
    ExpiresByType application/x-javascript "access plus 1 week"
    ExpiresByType image/x-icon "access plus 1 year"
    ExpiresByType image/svg+xml "access plus 1 year"
    ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
    ExpiresByType application/font-woff "access plus 1 year"
    ExpiresByType application/x-font-woff "access plus 1 year"
    ExpiresByType font/woff2 "access plus 1 year"
    ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
    ExpiresByType font/opentype "access plus 1 year"
    ExpiresByType font/ttf "access plus 1 year"
    ExpiresByType font/otf "access plus 1 year"
    ExpiresByType application/x-font-ttf "access plus 1 year"
    ExpiresByType application/x-font-otf "access plus 1 year"
</IfModule>

<IfModule mod_headers.c>
    Header unset Etag
</IfModule>
FileETag none
<IfModule mod_deflate.c>
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/x-javascript font/ttf application/x-font-ttf font/otf application/x-font-otf font/opentype image/svg+xml
    </IfModule>
</IfModule>

#If rewrite mod isn't enabled
ErrorDocument 404 /index.php?controller=404

# ~~end~~ Do not remove this comment, Prestashop will keep automatically the code outside this comment when .htaccess will be generated again

前もって感謝します!

回答

BrunoLeveque May 09 2019 at 16:50

これは機能し、古い製品のURLを新しいURLに永続的にリダイレクトします(オプション#1)。

  1. 以下のスクリプトをPrestaShopルートフォルダーに配置します
  2. オプション:構成に一致するようにパラメーターid_shopid_langパラメーターを編集します
  3. それを起動し、直後に結果をコピーして.htaccessファイルに貼り付けますRewriteEngine on-スクリプトを削除します
  4. Voilà!

脚本:

<?php

include('config/config.inc.php');
include('init.php');

$context = Context::getContext(); $products = Db::getInstance()->ExecuteS('
SELECT p.id_product, pl.link_rewrite prod_url, cl.link_rewrite cat_url
FROM '._DB_PREFIX_.'product p
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (pl.id_product = p.id_product)
LEFT JOIN '._DB_PREFIX_.'category_lang cl ON (cl.id_category = p.id_category_default)
WHERE p.active = 1 AND cl.id_lang = 1 AND cl.id_shop = 1 AND pl.id_lang = 1 AND cl.id_shop = 1');

foreach ($products as $p)
{
    $new_url = $context->link->getProductLink(new Product((int)$p['id_product'])); echo 'RewriteRule ^'.$p['cat_url'].'/'.$p['prod_url'].'$ '.$new_url.' [L,R=301]<br />';
}

出力(2つの製品しかないPrestaShopデモストア):

RewriteRule ^men/hummingbird-printed-t-shirt$ http://localhost/prestashop/1-hummingbird-printed-t-shirt.html [L,R=301]
RewriteRule ^women/brown-bear-printed-sweater$ http://localhost/prestashop/2-brown-bear-printed-sweater.html [L,R=301]

コピー/貼り付け後の.htaccessファイル:

...
<IfModule mod_rewrite.c>
<IfModule mod_env.c>
SetEnv HTTP_MOD_REWRITE On
</IfModule>

RewriteEngine on

# Permanent redirections
RewriteRule ^men/hummingbird-printed-t-shirt$ http://localhost/prestashop/1-hummingbird-printed-t-shirt.html [L,R=301]
RewriteRule ^women/brown-bear-printed-sweater$ http://localhost/prestashop/2-brown-bear-printed-sweater.html [L,R=301] #Domain: localhost RewriteRule . - [E=REWRITEBASE:/prestashop/] RewriteRule ^api$ api/ [L]
...

オプション#2は、コンバージョン率の観点からは実行可能ではないようです。

これがお役に立てば幸いです。

そうでない場合は、モジュールの開発者に更新バージョンを依頼します。これがどれほど時間がかかるかを考えると、25ドルはアップグレードするのに妥当なコストのようです。

MahdiShad May 09 2019 at 10:25

製品IDがURLから削除されていることを考えると、Htaccessを介してそれらをリダイレクトすることはできないと思います。ヒント:htaccessファイルにURLルールを1行ずつ追加することはできません。それはあなたのサイトを遅くします。すべてのルールは、サイトからの要求に応じてチェックされます(cssリンク、jsリンク、画像など)

これを行うには、URLをチェックしてリダイレクトする新しいコントローラーが必要です。実際、この問題を修正するには別のモジュールが必要です。オーバーライドを元に戻す必要があります。

-そのため、PrestaShopのURLからIDを削除するようにお客様にアドバイスすることはありません。