URL Reescrevendo OpenCart Products SEO

9

Gostaria de reescrever o URL do meu produto na minha loja virtual. Opencart em si tem uma implementação de SEO que realmente é uma porcaria. Atualizamos a implementação do SEO para poder usar a mesma palavra-chave para várias categorias. Consulte: Palavras-chave duplicadas do Opencart Mas isso só funciona para as categorias. Para os produtos eu precisaria apenas de uma regra de reescrita do htaccess, eu acho.

O URL original é assim:

http://domain.com/index.php?route=product/product&path=25_28_93&product_id=1759

minha URL está assim no momento:

http://domain.com/In-Stock/Retreaded-Tires/Agricultural?product_id=1759

Como você pode ver, as categorias já foram alteradas.

E eu quero que seja assim:

http://domain.com/In-Stock/Retreaded-Tires/Agricultural/1759/1050-50R32-Mega-X-Bib

Então, para paginação (dentro de uma categoria) eu tenho este URL:

http://domain.com/index.php?route=product/category&path=36_70_67&page=2

Eu já fiz isso em:

http://domain.com/Tire-Retreading/Equalizing/&page=2

Mas eu gostaria que isso fosse

http://domain.com/Tire-Retreading/Equalizing/2

Meu arquivo htaccess tem esta aparência:

Options +FollowSymlinks
Options -Indexes
<FilesMatch "(?i)((\.tpl|\.ini|\.log|(?<!robots)\.txt))">
 Order deny,allow
 Deny from all
</FilesMatch>
RewriteEngine On
RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^download/(.*) /index.php?route=error/not_found [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

Meu arquivo seo_url.php que é um pouco alterado se parece com isto:

public function index() {
    $this->load->model('catalog/category');
    // Add rewrite to url class
    if ($this->config->get('config_seo_url')) {
        $this->url->addRewrite($this);
    }

    // Decode URL
    if (isset($this->request->get['_route_'])) {
        $parts = explode('/', $this->request->get['_route_']);

        // remove any empty arrays from trailing
        if (utf8_strlen(end($parts)) == 0) {
            array_pop($parts);
        }

        $categories = array();

        for ($i = 0; $i < count($parts); $i++) {
            $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($parts[$i]) . "'");

            if ($query->num_rows) {
                $url = explode('=', $query->row['query']);

                if ($url[0] == 'product_id') {
                    $this->request->get['product_id'] = $url[1];
                }

                if ($url[0] == 'category_id') {
                    $categories[$i] = $this->model_catalog_category->getCategory($url[1]);

                    if (!isset($this->request->get['path'])) {
                        $this->request->get['path'] = $categories[$i]['category_id'];
                    } else {
                        foreach ($query->rows as $row) {
                            $url = explode('=', $row['query']);
                            $category_id = $url[1];

                            $category = $this->model_catalog_category->getCategory($category_id);

                            if ($category['parent_id'] == $categories[$i - 1]['category_id']) {
                                $this->request->get['path'] .= '_' . $category['category_id'];
                            }
                        }
                    }
                }

                if ($url[0] == 'manufacturer_id') {
                    $this->request->get['manufacturer_id'] = $url[1];
                }

                if ($url[0] == 'information_id') {
                    $this->request->get['information_id'] = $url[1];
                }

                if ($query->row['query'] && $url[0] != 'information_id' && $url[0] != 'manufacturer_id' && $url[0] != 'category_id' && $url[0] != 'product_id') {
                    $this->request->get['route'] = $query->row['query'];
                }

            } else {
                $this->request->get['route'] = 'error/not_found';

                break;
            }
        }

        if (!isset($this->request->get['route'])) {
            if (isset($this->request->get['product_id'])) {
                $this->request->get['route'] = 'product/product';
            } elseif (isset($this->request->get['path'])) {
                $this->request->get['route'] = 'product/category';
            } elseif (isset($this->request->get['manufacturer_id'])) {
                $this->request->get['route'] = 'product/manufacturer/info';
            } elseif (isset($this->request->get['information_id'])) {
                $this->request->get['route'] = 'information/information';
            }
        }

        if (isset($this->request->get['route'])) {
            return new Action($this->request->get['route']);
        }
    }
}

public function rewrite($link) {
    $url_info = parse_url(str_replace('&amp;', '&', $link));

    $url = '';

    $data = array();

    parse_str($url_info['query'], $data);

    foreach ($data as $key => $value) {
        if (isset($data['route'])) {
            if (($data['route'] == 'product/product' && $key == 'product_id') || (($data['route'] == 'product/manufacturer/info' || $data['route'] == 'product/product') && $key == 'manufacturer_id') || ($data['route'] == 'information/information' && $key == 'information_id')) {
                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE 'query' = '" . $this->db->escape($key . '=' . (int)$value) . "'");

                if ($query->num_rows && $query->row['keyword']) {
                    $url .= '/' . $query->row['keyword'];

                    unset($data[$key]);
                }
            } elseif ($key == 'path') {
                $categories = explode('_', $value);

                foreach ($categories as $category) {
                    $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE 'query' = 'category_id=" . (int)$category . "'");

                    if ($query->num_rows && $query->row['keyword']) {
                        $url .= '/' . $query->row['keyword'];
                    } else {
                        $url = '';

                        break;
                    }
                }

                unset($data[$key]);
            } else  {
                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE 'query' = '" .$data['route'] . "'");

                if ($query->num_rows && $query->row['keyword']) {
                    $url .= '/' . $query->row['keyword'];

                    unset($data[$key]);
                }
            }
        }
    }

    if ($url) {
        unset($data['route']);

        $query = '';

        if ($data) {
            foreach ($data as $key => $value) {
                $query .= '&' . rawurlencode((string)$key) . '=' . rawurlencode((string)$value);
            }

            if ($query) {
                $query = '?' . str_replace('&', '&amp;', trim($query, '&'));
            }
        }

        return $url_info['scheme'] . '://' . $url_info['host'] . (isset($url_info['port']) ? ':' . $url_info['port'] : '') . str_replace('/index.php', '', $url_info['path']) . $url . $query;
    } else {
        return $link;
    }
}

O código de paginação é assim:

class Pagination {
    public $total = 0;
    public $page = 1;
    public $limit = 20;
    public $num_links = 8;
    public $url = '';
    public $text_first = '|&lt;';
    public $text_last = '&gt;|';
    public $text_next = '&gt;';
    public $text_prev = '&lt;';

    public function render() {
        $total = $this->total;

        if ($this->page < 1) {
            $page = 1;
        } else {
            $page = $this->page;
        }

        if (!(int)$this->limit) {
            $limit = 10;
        } else {
            $limit = $this->limit;
        }

        $num_links = $this->num_links;
        $num_pages = ceil($total / $limit);

        $this->url = str_replace('%7Bpage%7D', '{page}', $this->url);

        $output = '<ul class="pagination">';

        if ($page > 1) {
            $output .= '<li><a href="' . str_replace('{page}', 1, $this->url) . '">' . $this->text_first . '</a></li>';
            $output .= '<li><a href="' . str_replace('{page}', $page - 1, $this->url) . '">' . $this->text_prev . '</a></li>';
        }

        if ($num_pages > 1) {
            if ($num_pages <= $num_links) {
                $start = 1;
                $end = $num_pages;
            } else {
                $start = $page - floor($num_links / 2);
                $end = $page + floor($num_links / 2);

                if ($start < 1) {
                    $end += abs($start) + 1;
                    $start = 1;
                }

                if ($end > $num_pages) {
                    $start -= ($end - $num_pages);
                    $end = $num_pages;
                }
            }

            for ($i = $start; $i <= $end; $i++) {
                if ($page == $i) {
                    $output .= '<li class="active"><span>' . $i . '</span></li>';
                } else {
                    $output .= '<li><a href="' . str_replace('{page}', $i, $this->url) . '">' . $i . '</a></li>';
                }
            }
        }

        if ($page < $num_pages) {
            $output .= '<li><a href="' . str_replace('{page}', $page + 1, $this->url) . '">' . $this->text_next . '</a></li>';
            $output .= '<li><a href="' . str_replace('{page}', $num_pages, $this->url) . '">' . $this->text_last . '</a></li>';
        }

        $output .= '</ul>';

        if ($num_pages > 1) {
            return $output;
        } else {
            return '';
        }
    }
}

EDITAR:

Todas as minhas páginas são redirecionadas para o link De lá, ele decide qual diretório / arquivo usar a partir do parâmetro route. Então route=product/product está dizendo para ir para o product.php dentro do produto de diretório. O produto de diretório também contém categories.php , o que leva a uma rota: route=product/category

A variável Path da string representa o id de uma categoria. No meu exemplo 25 significa In-Stock . E 25_28 significa In-Stock/Retreaded-Tires etc.

A variável product_id representa o ID correspondente do produto.

A variável de página representa a paginação e é usada na lista de produtos dentro de uma categoria. Essa lista pode ter um comprimento variável, pois calcula quantos produtos estão dentro de uma categoria e quantos ele deve mostrar em uma página. Portanto, se o URL original tiver &page=2 com a rota route=product/category , ele deverá criar uma URL assim: http://domain.com/Tire-Retreading/Equalizing/2

    
por Baklap4 22.10.2015 в 12:16
fonte

1 resposta

2

Ainda acho as explicações adicionadas confusas e parece-me que você não sabe exatamente como a regravação de URL funciona, por isso vou tentar explicar algumas noções básicas sobre reescrita de URLs .

O que você pode fazer com a regravação de URL é traduzir segmentos 'bonitos' de URL (de URLs mostrados para o usuário) em segmentos de seu real, longo URLs 'não muito bonitos' (que usam variáveis para servir determinados conteúdos). Você faz isso usando expressões regulares para combinar com os segmentos bonitos e, em seguida, fornecendo valores pré-definidos ou aqueles valores correspondentes às variáveis do PHP.

Então, o que você faz primeiro é descobrir como suas URLs bonitas devem ser e como seus segmentos individuais são traduzidos em suas variáveis. (Embora você também possa usar qualquer número de novas variáveis, cujos valores você pode converter e atribuir a variáveis já existentes ou pré-definidas em seus scripts php.)

Você deu este exemplo:      link

Este URL parece ser composto de três partes que você deseja traduzir para variáveis:

  • Tire-Retreading (variável route )
  • Equalizing (variável path )
  • 2 (variável page )

Terá de criar o seu RegEx para corresponder os seus segmentos com base em todas as formas possíveis de os segmentos individuais poderem ser escritos, incluindo quaisquer caracteres especiais permitidos, etc. Assim que isso for feito, pode transmitir os valores correspondentes às suas variáveis usando uma backreference (ou você pode definir seus próprios valores para serem usados por suas variáveis).

Usando backreferences, você poderia usar isso:

RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)/([0-9]+)$ index.php?route=$1&path=$2&page=$3 [NC,L]

Você terá que colocar o RegEx individual para a correspondência de segmento (como [A-Za-z-]+ ) entre colchetes para poder atribuir os resultados às suas variáveis php na forma de $1 , $2 etc.

Dependendo de se os usuários também devem ter permissão para navegar nas páginas "visão geral" de seus produtos / categorias ou caminhos, talvez seja necessário começar a reescrever do menor URL possível para o mais longo possível.

Por exemplo,

RewriteRule ^([A-Za-z-]+)$ $1/ [NC,R]
RewriteRule ^([A-Za-z-]+)/$ index.php?route=$1 [NC,L]
RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)$ $1/$2/ [NC,R]
RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)/$ index.php?route=$1&path=$2 [NC,L]
RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)/([0-9]+)$ $1/$2/$3/ [NC,R]
RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)/([0-9]+)/$ index.php?route=$1&path=$2&page=$3 [NC,L]

A reescrita do domínio em si vai antes de toda a reescrita do 'caminho'.

Você também terá que descobrir quais flags - a parte entre colchetes no final - você precisa usar, o que significa que você terá que ler em regravação de URL em mais detalhes. No exemplo acima, todos os URLs que o usuário digita que não terminam com uma barra são automaticamente redirecionados (é o que o R entre colchetes representa) para a mesma URL, mas com uma barra adicional. Então, http://example.com/blah iria redirecionar para http://example.com/blah/ etc.

Com base nas informações que você forneceu, você terá URLs começando com um dos dois segmentos possíveis:

http://example.com/In-Stock/...

vs.

http://example.com/Product-or-Category/....

Então, você terá que tomar cuidado extra que estes dois não fiquem confusos. Se In-Stock for canalizado para sua própria variável e for sempre escrito exatamente dessa forma, você provavelmente fará com que suas primeiras regras lidem com isso e use o RegEx para corresponder os produtos / categorias somente mais tarde (todas as regras de reescrita são tratadas cronologicamente, um após o outro).

Espero que ajude.

    
por Kay 01.11.2015 / 14:22
fonte