Joomla htaccess rewrite url - Parameter must index by a number - Why? - joomla

this is the firsttime a put a question here, so dont hard on me. Thank you.
I currently setup a joomla site. I create a page, and a new template, and a module, inside the template/index.php i call my module.
The original url that works is something like:
index.php/danh-sach-game?gt_name=game_mang_xa_hoi
danh-sach-game: is the page.
game-mang-xa-hoi: is the input parameter to the module.
everythings works find but i want to rewrite url to this:
danh-sach-game/game-mang-xa-hoi
So i created a .htaccess with content:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^danh-sach-game/(.*)$ index.php/danh-sach-game?gt_name=$1 [L]
</IfModule>
Now this is time for "MAGIC"
if i enter the url:
danh-sach-game/game-mang-xa-hoi
then Joomla push a message "An error has occurred.The requested page cannot be found."
But if i index the parameter by a number like this:
danh-sach-game/1-game-mang-xa-hoi (note: the number 1).
Then it works finds. Any paremeter index by a number will work find.
I rewrite url to a test file (replace index.php by test.php) than the page test.php receive the parameter as usuas, with or without number index the parameter.

This is because Joomla and most of the Joomla extensions uses ID column of the content as an identifier to look up the database. Some of the SEF tools (for example AceSef, sh404Sef) provide the facility to lookup using the alias name (the text after the number and hyphen) however with additional cost of database queries (they will in turn query for proper url internally).
The number in the last part of the URL will be processed and passed as ID of the particular page/content that you are viewing. This is done in the particular component's router.php file. So check the router.php file of the component you are using to check how the url gets parsed.

Related

Rewriting url with the following regular expression

I'm trying to do a mod rewrite to get this url: localhost/test/index.php?hello
I created a file for this page called hello.php and it is in the folder /test
To clarify, I have another page that has a link to my hello.php, but what is the correct url so I can display localhost/test/index.php?hello in the url when I click the link to access my hello.php page.
The following doesn't seem like it is right:
RewriteRule ^.*$ index.php?$1 [L]
Try this if you want to just do php files.
RewriteEngine on
RewriteRule (.*)\.php$ /index.php?$1 [L]
To clarify what my answer does. It gives you more friendly URLs which it sounded like what your were asking for.
So you can use localhost/hello.php and it will be internally redirect to /localhost/index.php?hello. Internally means they will never see localhost/index.php?hello and will always see localhost/hello.php in their browser.
You can do any URL and it will rewrite to a php file. e.g. localhost/index.php?newpage and you can use /localhost/newpage.php
Hope that is clearer.
EDIT
You want the reverse but I don't know how your PHP is constructed but query strings are typically field/value pairs. For example name=john, page=contact, action=hello etc. You have index.php?hello but hello has no content or value.
That's probably why you're having such a hard time even re-writing your URL. Using $_GETwould require a value.
So what I would do, is if your URL was like this using field/value pairs
index.php?action=hello
Then in the index.php file you could do something like
$action = $_GET["action"];
if($action == "hello"){
//show contents of hello, include a page or whatever
}
Once you have good URLs it would be easy to rewrite it.
So if the URL that you want shown is like
index.php?action=hello and you want to redirect it to hello.php
Your .htaccess would look like this
RewriteRule ^action=([^/]+) /$1.php [R,L]
That would redirect it to the php file. If you don't want to show the redirection and keep it an internal redirect you can remove the R flag and just keep [L].
I personally don't want the user to see really long query strings URL example. mysite.com?page=music&artist=someartist&title=sometitle
So all my URL's are rewritten to be shorter and friendlier like my original answer.
you don't need .htaccess for 2. as far as you're using GET parametr - use it in index.php:
if (isset($_GET['hello'])) include('hello.php');
this will show the contents of hello.php inside index.php

New NICE URLs with 301s. How to make them work Together?

I have this old website URL structure:
site.com/folder/prod.php?cat=MAIN%20CAT%20&prodid1=123&prodtitle=PROD%20TITLE&subcat=SUB%20CAT
and real example will be something like:
site.com/folder/prod.php?cat=CAR%20AUDIO&prodid1=4444&prodtitle=MTX%20AMPS&subcat=AMPS
here you can see that for the product page there are 4 variables: category, produt id, product title and sub category. Some of this variables were used to open a menu. And yes, the URL pulls variables with space and both lower and uppercase.
The new site url has a new structure:
site.com/x/product-title-prodid2
a rel example will be like:
site.com/x/mtx-amps-8888
Which is accomplish by using two variables (friendly slug + a second product id: prodid2) with the following code in the .htaccess
<IfModule mod_rewrite.c>
Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^p/(.*)/$ product.php?prodid2=$1
RewriteRule ^p/(.*)$ product.php?prodid2=$1
</IfModule>
Internally we can get prodid2 if we have prodid1 from the same table, but not viceversa.
Everything works fine, but we now have to create 301 redirects and apparently since the same variables are not used in the old / new url, then it becomes tricky since apparently we have to create a single rule for the nice URL creation and the 301s?
We have tried adding the following to the htaccess:
RewriteCond %{QUERY_STRING} ^cat=CAR%20AUDIO&prodid1=4444&prodtitle=MTX%20AMPS&subcat=AMPS$ [NC]
RewriteRule ite.com/folder/prod.php site.com/x/mtx-amps-8888? [R=301,L]
and it works for only 1 product, but when adding 2 or more, the site goes down. I imaging this would be an infinite loop?
An alternative would be adding a:
ErrorDocument 404 /404.php
to get the URL and redirect to the page, but this would be ugly for SEs.
UPDATE:
Sorry for my lack of understanding on this topic, am very new to this.
The product has 2 important ids. For example:
MTX AMP (which is the actual product title) if listed in 3 categories will have 1 single prodid2 repeated and 3 different prodid1 (1 for each category). They all reside in the same table. So, if we have a prodid1 we can get the prodid2 which is right next to it in the db table.
The rule to get a nice URL on the new site is pulled using prodid2
RewriteRule ^p/(.*)$ product.php?prodid2=$1
which brings the complete value stored in the database. e.g. mtx-amps-8888 << this is a mix of a slug + the prodid2
complete url is:
site.com/p/mtx-amps-888
(the p is just a virtual forder and we take advantage of that variable to show the right page template)
So mtx-amps-888 are not 3 keys, these are generated when creating a product and saved all together in a single field in the db. They already include the separation - so this is not done in the htaccess.
The cat (key) value is really used to expand a menu used in the old site with, but to create the 301 redirect we would probably use prodid1 since we can match that value to get a prodid2. prodid2 is used as the main query to get the nice URL in the new site and its value will bring the nice URL stored in the db.
What makes sense from all my research would be the following:
<IfModule mod_rewrite.c>
Options +Indexes
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
RewriteRule ^p/(.*)$ product.php?prodid2=$1
RewriteCond %{QUERY_STRING} ^cat=CAR%20AUDIO&prodid1=4444&prodtitle=MTX%20AMPS&subcat=AMPS$ [NC]
RewriteRule ite.com/folder/prod.php site.com/x/mtx-amps-8888? [R=301,L]
RewriteCond %{QUERY_STRING} ^cat=CAR%20AUDIO&prodid1=5555&prodtitle=BOSS%20AMPS&subcat=AMPS$ [NC]
RewriteRule ite.com/folder/prod.php site.com/x/mtx-amps-8888? [R=301,L]
RewriteCond %{QUERY_STRING} ^cat=CAR%20VIDEO&prodid1=6666&prodtitle=ALPINE%20DVDS&subcat=DVD%20PLAYERS$ [NC]
RewriteRule ite.com/folder/prod.php site.com/x/mtx-amps-8888? [R=301,L]
</IfModule>
Pls note that I removed a line from the main rewrite rule:
RewriteRule ^p/(.*)/$ product.php?prodid2=$1
This only assures that the user can also use / at the end of the URL: site.com/p/mtx-amps-888/
I also repeated the rewrite condition for the 301 redirects of 3 products, but i really have about 3K products to list here. If I keep 1, it will work but if I add 2, I believe a loop is created.
Hopefully this makes sense. You have no idea how important is for me to get this up and running, so my best wishes to those who can help :)
Just re-create the file /folder/prod.php and have php do the redirect. This is the easiest and cleanest solution.
<?php
$prodid1 = $_GET['prodid1'];
//calculate prodid2 based on prodid1, or use mysql to retreive the prodid2 belonging to prodid1
$prodid2 = $prodid1;//just for testing
$newpath = "/p/$prodid2/";
// redirect using 301
header("Location: http://{$_SERVER['HTTP_HOST']}{$newpath}");
header('HTTP/1.1 301 Moved Permanently');
?>

Mod_rewrite - don't display certain query string in the url

I know this question may have been asked several times, but to be honest I haven't yet found a complete answer for this.
I have this url:
modelDetails.php?manufacturerName=$1&manfuacturerID=$2&modelName=$3&modelID=$4&yachtCode=$5&lang=$6
Is it possible not to display yachtCode and lang in the url and still pass the values from page to page?
This is my htacces file:
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^(.*)\.html$ $1.php [nc]
RewriteCond %{QUERY_STRING} ^lang=(EN|DE|NL)$ [NC]
RewriteRule ^(.*)/([0-9]+)/(.*)/([0-9]+)/([0-9]+)$ modelDetails.php?manufacturerName=$1&manufacturerID=$2&modelName=$3&modelID=$4&yachtCode=$5 [L,QSA]
If you remove the data from the query string, then the only other way to access the data is to retrieve it from a cookie. But to set the cookie you'll have to have the yachtCode value appear in the query string at some point.
The only alternative would be to use POST (the mode used by a web form) instead of GET (the mode which is generally used). POST mode submits variables as part of the request, rather than adding the variables to the query string. But you can't force a hyperlink to use POST mode, so this is probably not of use to you.
In short, you probably can't hide yachtCode from the end user completely.

Rewrite Condition not working for Rewrite rule on individual pages

I am trying to write a rule that will capture any url that does NOT have sales/anything up to a .php or .php3 file and anything after that - if there is anything - and rewrite that to a new website as per below:
RewriteCond %{REQUEST_URI} !^(/sales/.*php3?).*
RewriteRule ^/sales/([^./]*)$ http://www2.domain.com/sales$1/index.shtml [R,L]
It captures if I put in www.domain.com/sales but if I put in just http://www.domain.com/sales/trucks.shtml if does not capture the individual pages.
Can anyone see what I need to do to get this to work correctly please ?
To clarify:
.If I put in url www.domain.com/sales, the site redirects to www2.domain.com/sales/index.shtml ....however if I put in the url www.domain.com/sales/trucks.shtml the condition is not picked up and the url does not rewrite to the ww2 site so I am stuck on the old page still ....thanks for your help
Alright use these 2 rules for your requirements:
RewriteRule ^sales/?$ http://www2.domain.com/sales/index.shtml [R,L,NC]
RewriteRule ^sales/(?!.*\.php3?$).*$ http://www2.domain.com%{REQUEST_URI} [R,L,NC]

Getting the original REQUEST_URI when using mod_rewrite AND mod_proxy

I'm using a custom.conf file for rewrites and codeigniter for some features of the site, mainly the articles.
My original url gets rewritten, so I have http://example.com/article-a101, this uses the custom.conf file to rewrite to codeigniter/article/read/101. I think I must send this as a proxy call using the [P] flag in mod_rewrite to make it rewrite again in codeigniters .htaccess file. Once it hits the code igniter .htaccess, it uses that mod rewrite structure to call the index file and use the article controller and the read function sending in the 101 as the parameter.
What I'm trying to figure it is how do I get the original url in the address bar as its not in the $_SERVER variable. Since I use the [P] on the first rewrite, request_uri has codeigniter/article/read/101.
custom.conf
RewriteRule ^/([_a-zA-Z0-9-]+)-a([0-9]+)$ /codeigniter/article/read/$2 [P,L]
codeigniters .htaccess, fairly basic
RewriteRule ^(.*)$ index.php?/$1 [L]
Here's my current solution that I know there must be a better method for
RewriteRule ^/([_a-zA-Z0-9-]+)-a([0-9]+)$ /codeigniter/article/read/$2?orig_url=%{REQUEST_URI}&%{QUERY_STRING} [P,L]
This stays hidden from the user, and I can access the original url through the query string, but doesn't seem like an elegant solution.
I'm pretty sure you cant do it any other way with mod_rewrite
but you could do it with codeigniter routing.
$route['^([_a-zA-Z0-9-]+)-a([0-9]+)$'] = "article/read/$2";
assuming your controller is named article and your function is named read
if you visited /article-a101
then $this->uri->uri_string(); would return article-a101 (the original url, which should be in your url bar now)
and $this->uri->ruri_string(); would return article/read/101 (where you actually are)

Resources