Asked  7 Months ago    Answers:  5   Viewed   32 times

I'm having a hard time with .htaccess. I want to create friendly URLs for a site I'm working on...

Basically I want to convert this:

http://website.com/index.php?ctrl=pelicula&id=0221889
http://website.com/index.php?ctrl=pelicula&id=0160399&tab=posters

Into this:

http://website.com/pelicula/0221889/
http://website.com/pelicula/0221889/posters/

In case I need it later I would also want to know how to add the article title to the end of the URL like this (I'm using PHP):

http://website.com/pelicula/0221889/the-article-name/
http://website.com/pelicula/0221889/the-article-name/posters/

Note: Stackoverflow method is also good for me, for example the url of this question is:

http://stackoverflow.com/questions/3033407/htacces-to-create-friendly-urls-help-needed

But you can put anything after the id and it will also work. like this:

http://stackoverflow.com/questions/3033407/just-anything-i-want

I have used some automatic web tools for creating the .htacces file, but its not working correctly. So I ask for your help.

I will also be glad if you can recommend .htacces best practices and recommendations..

EDIT: based on some answers I get here I put this:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^/([^/]+)/([^/]+)/?([^/]*)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
</IfModule>

But I get the default host 'page not found' error.

I also tried:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^([^/]+)/(d+)/([^/]+)/?$ index.php?ctrl=$1&id=$2&tab=$3 [QSA,L]
    RewriteRule ^([^/]+)/(d+)/?$         index.php?ctrl=$1&id=$2 [QSA,L]
    RewriteRule ^([^/]+)/?$               index.php?ctrl=$1 [QSA,L]
</IfModule>

This also does not work. It takes me to my default 404.php page.

mod_rewrite is enabled and working.

Help!

 Answers

62

In the document root for http://website.com/ I'd put an htaccess file like this:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

Then in your PHP script you can manipulate the $_GET['url'] variable as you please:

$path_components = explode('/', $_GET['url']);
$ctrl=$path_components[0];
$id=$path_components[1];
$tab=$path_components[2];
Wednesday, March 31, 2021
 
Raef
answered 7 Months ago
67

You have limited "rewrite loop" (limited to 2 iterations only). Use these rules:

# do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]

RewriteRule ^([a-z0-9_-]+)(.php)?$ index.php?page=$1 [NC,L,QSA]

If you do not like it, here is an alternative (but I still prefer #1, but maybe this one will be better for your setup/app logic -- this assumes that index.php is located in website root folder):

RewriteCond %{REQUEST_URI} !^/index.php
RewriteRule ^([a-z0-9_-]+)(.php)?$ index.php?page=$1 [NC,L,QSA]
Saturday, May 29, 2021
 
pamelus
answered 5 Months ago
32

To ignore the files that exists just ignore the "RewriteCond"s.

Just rewrite everything that comes into services/ to api.php?service ...

Put this into your services folder.

Be careful with your encoding, save the file as .htaccess with a encode that your server reads.

# .htaccess mod_rewrite

RewriteEngine On

RewriteRule ^(.*)$ api.php?service=$1 [QSA,L]

If you don't need to avoid Files, then just go to:

# .htaccess mod_rewrite

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l

RewriteRule ^(.*)$ api.php?service=$1 [QSA,L]
Saturday, May 29, 2021
 
Farnabaz
answered 5 Months ago
40

It turns out this can be done with a relatively simple change to a single file. No .htaccess rewrite rules, simply patch the catalog/controller/common/seo_url.php file and add your pretty URLs to an existing database table.


The patch to seo_url.php:

Index: catalog/controller/common/seo_url.php
===================================================================
--- catalog/controller/common/seo_url.php   (old)
+++ catalog/controller/common/seo_url.php   (new)
@@ -48,7 +42,12 @@
                $this->request->get['route'] = 'product/manufacturer/product';
            } elseif (isset($this->request->get['information_id'])) {
                $this->request->get['route'] = 'information/information';
-           }
+           } else {
+                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($this->request->get['_route_']) . "'");
+                if ($query->num_rows) {
+                    $this->request->get['route'] = $query->row['query'];
+                }
+           }

            if (isset($this->request->get['route'])) {
                return $this->forward($this->request->get['route']);
@@ -88,7 +87,15 @@
                        }

                        unset($data[$key]);
-                   }
+                   } else {
+                        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = '" . $this->db->escape($data['route']) . "'");
+
+                        if ($query->num_rows) {
+                            $url .= '/' . $query->row['keyword'];
+
+                            unset($data[$key]);
+                        }
+                   }
                }
            }

There are two edits required. The first extends the index() function to look in the url_alias table for any keyword matching $this->request->get['_route_'].

The second extends the rewrite() function to look in the url_alias table for all routes, not just those for products, manufacturers, and information pages.


Adding entries to the database:

INSERT INTO `url_alias` (`url_alias_id`, `query`, `keyword`) VALUES
(NULL, 'checkout/cart', 'cart');

That's it. http://example.com/cart should return the same thing that http://example.com/index.php?route=checkout/cart does, and OpenCart should recognize $this->url->link('checkout/cart'); and return a link to the pretty URL http://example.com/cart

Monday, June 21, 2021
 
Len_D
answered 4 Months ago
88

Value retrieved from the cell is already in Unicode.

StrConv(vbUnicode) gives you "double unicode" which is broken because it went through a conversion using the current sustem codepage.
Then the Print command converts it back to "single unicode", again using the current system codepage. Don't do this. You're not saving unicode, you're saving invalid something that may only appear valid on your particular computer under your current settings.

If you want to output Unicode data (that is, avoid the default VB mechanism of auto-converting output text from Unicode to ANSI), you have several options.

The easiest is using FileSystemObject without trying to invent anything about unicode conversions:

With CreateObject("Scripting.FileSystemObject")
  With .CreateTextFile("C:" & Cells(1).Value & ".txt", , True)
    .Write Cells(1).Value
    .Close
  End With
End With

Note the last parameter that controls Unicode.

If you don't want that, you can declare CreateFileW and WriteFile functions:

Private Declare Function CreateFileW Lib "kernel32.dll" (ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByRef lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Declare Function WriteFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, ByRef lpNumberOfBytesWritten As Long, ByRef lpOverlapped As Any) As Long

Private Const CREATE_ALWAYS As Long = 2
Private Const GENERIC_WRITE As Long = &H40000000
Dim hFile As Long
hFile = CreateFileW(StrPtr("C:" & Cells(1).Value & ".txt"), GENERIC_WRITE, 0, ByVal 0&, CREATE_ALWAYS, 0, 0)

Dim val As String
val = Cells(1).Value

WriteFile hFile, &HFEFF, 2, 0, ByVal 0&  'Unicode byte order mark (not required, but to please Notepad)
WriteFile hFile, ByVal StrPtr(val), Len(val) * 2, 0, ByVal 0&

CloseHandle hFile
Sunday, July 4, 2021
 
pop
answered 4 Months ago
pop
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :