2015-10-22 15 views
9

Mi piacerebbe riscrivere gli URL dei miei prodotti dal mio webshop di opencart. Opencart stesso ha un'implementazione seo che fa davvero schifo. Ho aggiornato l'implementazione di SEO per poter utilizzare la stessa parola chiave per più categorie: Opencart duplicate URL keywords Ma questo funziona solo per le categorie. Per i prodotti avrei solo bisogno di una regola di riscrittura htaccess, penso.Riscrittura URL Prodotti OpenCart SEO

l'URL originale si presenta così:

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

mio URL appare come questo al momento:

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

Come si può vedere le categorie è cambiata già.

E io voglio che sia così:

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

Poi per l'impaginazione (all'interno di una categoria) ho questo url:

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

Ho già fatto questo in:

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

ma mi piacerebbe che si tratta da

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

Il mio file .htaccess si presenta così:

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] 

sguardi Il mio file seo_url.php che è un po 'alterata come questo:

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; 
    } 
} 

Il codice di impaginazione è il seguente:

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 ''; 
     } 
    } 
} 

EDIT:

Tutte le mie pagine vengono reindirizzate al http://domain.com/index.php Da lì si decide quale directory/file da utilizzare dal parametro percorso. Quindi route=product/product sta dicendo andare al product.php all'interno del prodotto di directory. Il prodotto directory contiene anche categories.php che porta a un percorso: route=product/category

La variabile Percorso dalla stringa rappresenta l'ID di una categoria. Nel mio esempio 25 sta per In-Stock. E 25_28 corrisponde a In-Stock/Retreaded-Tires ecc.

La variabile product_id rappresenta l'id corrispondente per il prodotto.

La variabile di pagina rappresenta l'impaginazione e viene utilizzata nell'elenco di prodotti all'interno di una categoria. Questo elenco può avere una lunghezza variabile poiché calcola il numero di prodotti presenti in una categoria e il numero che deve mostrare su una pagina. Quindi, se l'URL originale ha &page=2 con il percorso route=product/category dovrebbe fare un URL simile a questo: http://domain.com/Tire-Retreading/Equalizing/2

+2

dove è il metodo di riscrittura, che deve essere in questo controller. – mcklayin

+0

Il metodo di riscrittura è stato aggiunto per errore ho lasciato fuori quel metodo. – Baklap4

+0

Puoi chiarire cosa intendi con 'Cosa viene usato più spesso e dovrei usare?' - Sembra che manchi una parola alla fine della frase e non è chiaro quali opzioni stai cercando di decidere tra. Non ho familiarità con Opencart ma conosco il mio modo di esplorare .htaccess. Tuttavia, dagli URL che hai fornito è difficile stabilire quali parti sono (senza passare per tutto il codice). In che modo gli URL desiderati si suddividono nei diversi elementi? (Ad esempio, che cosa: rotta, prodotto, percorso, categoria ecc. Negli URL "brutti" originali si traducono negli URL "puliti" desiderati?) Grazie. – Kay

risposta

2

ho ancora trovare le spiegazioni aggiunto confusione e suona per me come non si sa bene come la riscrittura degli URL lavori, in modo da Proverò a spiegare alcune nozioni di base sulla riscrittura degli URL.

Che cosa si può fare con la riscrittura degli URL è di tradurre 'Pretty' URL segmenti (di URL indicati per l'utente) in segmenti dei vostri effettivi URL lunghi, 'non belle' (che uso variabili per servire determinati contenuti). Lo fai usando le espressioni regolari per abbinare i bei segmenti, e quindi dando valori predefiniti o quei valori abbinati alle tue variabili php.

Quindi, ciò che fai per primo è capire come dovrebbero apparire i tuoi bei URL e come i loro singoli segmenti si traducono in variabili. (Anche se è possibile, naturalmente, anche utilizzare qualsiasi numero di nuove variabili, i cui valori è possibile convertire e assegnare ai già esistenti o pre-definite variabili negli script php.)

ti ha dato questo esempio: http://example.com/Tire-Retreading/Equalizing/2

Questo URL sembra essere composta da tre parti che si desidera tradurre in variabili:

  • Tire-Retreading (variabile route)
  • Equalizing (variabile path)
  • 2 (variabile page)

Dovrete costruire il tuo RegEx per la corrispondenza i segmenti in base a tutti i modi possibili i singoli segmenti possono essere scritti, tra cui tutti i caratteri speciali che sono consentiti, ecc Una volta fatto, è possibile passare i valori corrispondenti alle variabili usando un backreference (oppure è possibile definire i propri valori che devono essere utilizzati dalle variabili).

Utilizzando backreference, si potrebbe usare questo:

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

dovrete mettere il RegEx individuale per l'abbinamento segmento (come [A-Za-z-]+) tra parentesi tonde per essere in grado di assegnare i risultati al tuo php variabili in forma di $1, $2 ecc

a seconda se gli utenti dovrebbero essere autorizzati a sfogliare le pagine 'Panoramica' per i vostri prodotti/categorie o percorsi o no, potrebbe essere necessario avviare la riscrittura dal più piccolo possibile ' piuttosto 'URL al più lungo.

E.g.

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] 

La riscrittura per il dominio stesso va prima di tutto il 'percorso' riscritto.

Dovrai anche capire quali flag - la parte tra parentesi quadre alla fine - devi usare, il che significa che devi leggere su URL rewriting in modo più dettagliato.Nell'esempio precedente, tutti gli URL in cui l'utente digita che non termina con una barra vengono automaticamente reindirizzati (ovvero ciò che rappresenta lo R tra parentesi quadre) con lo stesso URL ma con una barra aggiunta. Così, http://example.com/blah sarebbe reindirizzare a http://example.com/blah/ ecc

In base alla informazioni che hai fornito, avrete gli URL che iniziano con uno dei due possibili segmenti:

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

vs.

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

Così , dovrai prestare particolare attenzione a questi due non confondersi. Se In-Stock viene incanalato nella propria variabile ed è sempre scritto esattamente in quel modo, probabilmente vorrai che le tue prime regole vengano trattate in quel modo e usare il RegEx per far corrispondere i prodotti/le categorie solo più tardi (tutte le regole di riscrittura sono trattate cronologicamente, uno dopo l'altro).

Spero che questo aiuti.