.htaccess RewriteRule not working, need to generate a URL friendly - .htaccess

I have this dynamic link:
http://www.nortedigital.mx/article.php?id=36175&t=dobla_las_manos_el_snte__avala_reforma_educativa
and I need to convert in URL friendly like this:
http://www.nortedigital.mx/36174/se_enriquecio_elba_en_sexenios_del_pan.html
and i have this RewriteRule:
RewriteRule ^([^/]*)/([^/]*)\.html$ /article.php?id=$1&t=$2 [L]
but doesn't work. Please, anybody can help me?

You must capture the query string in a RewriteCond and use that in the RewriteRule
RewriteEngine On
RewriteCond %{QUERY_STRING} ^id=(\d+)&t=(.+)$
RewriteRule ^/?article\.php$ /%1/%2.html? [R,L]
This redirects the client to request i.e. /36174/se_enriquecio_elba_en_sexenios_del_pan.html. Now you must server the real page. For that, we add an additional rule, similar to the one you already have in your question
RewriteRule ^/?(.+?)/(.+?)\.html$ /article.php?id=$1&t=$2 [L]
But now, there's an endless redirect loop. We break this by using an environment variable. Here is the whole complete ruleset
RewriteEngine On
RewriteCond %{ENV:REDIRECT_SEO} ^$
RewriteCond %{QUERY_STRING} ^id=(\d+)&t=(.+)$
RewriteRule ^/?article\.php$ /%1/%2.html? [R,L]
RewriteRule ^/?(.+?)/(.+?)\.html$ /article.php?id=$1&t=$2 [L,E=SEO:1]
This rule does the redirect as above, as long as the environment variable is not set. And it serves the real page from article.php and sets the environment variable at the same time to prevent the loop.
You can use cookies for this purpose too. But that will break, if cookies are disabled in the client.

Related

Simple rewritecond in htaccess doesn't work as expected

This is super simple but it's driving me crazy! I have a website at http://example.org/ and a subdirectory at http://example.org/ccc/
I want to redirect anything outside of the /ccc/ directory to a different website.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/ccc/?.*
RewriteRule ^(.*)$ https://new-website.com/$1 [L]
But this code doesn't work, it redirects the /ccc/ directory. According to my research and testing with this htaccess tester, it should not redirect because the RewriteCond is checking against /ccc with optional slash and other characters after it.
What is happening? Does this look correct?
Edit: This method from this answer is also not working, the CCC domain is being redirected:
RewriteEngine on
RewriteRule ^ccc index.php [L]
RewriteRule (.*) https://new-website.com/$1 [R=301,L]
PHP 5.4.45, Apache/2.2.31
Assuming ccc/ directory doesn't have a separate .htaccess, you may use this rule:
RewriteEngine on
RewriteCond %{THE_REQUEST} !\s/ccc[/?\s] [NC]
RewriteRule ^ https://new-website.com%{REQUEST_URI} [L,R=301,NE]
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. An example value of this variable is GET /index.php?id=123 HTTP/1.1
It looks like [L] isn't behaving normally and I'm guessing it's the old version of Apache (2.2.31) because these rules worked on a separate website. I found this solution which seemed to work for this case, the third line below:
RewriteEngine on
RewriteRule ^ccc/? index.php [L]
RewriteCond %{ENV:REDIRECT_STATUS} != 200
RewriteRule ^(.*)$ https://new-website.com/$1 [L]
Explanation from that question:
The problem is that once the [L] flag is processed, all the next RewriteRules are indeed ignored, however, the file gets processed AGAIN from the begin, now with the new url.
This magic Condition will not process the catch all if the file was already redirected.

htaccess Rewrite Rule Not Redirecting?

I have the below rewrite rule and for the life of me can't figure out why it's not working, there are no errors in any logs and nothing being displayed on screen, I'm stumped.
It takes a session token and passes it through the url.
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^/\?action=logout;(.*)$ /forum/index.php?action=logout;$1 [NC,L]
I've also tried this with no luck, no errors or anything to suggest an issue.
RewriteCond %{QUERY_STRING} ^action=logout
RewriteRule ^/\?action=logout;(.*)$ /forum/index.php?action=logout;$1 [L,R=301]
Using QUERY_STRING is a good start.
Anyway, you now need to match / or /index.php in your rule.
Also, since you're passing the same query string, you don't need to capture a part of it. You can use QSA flag instead.
RewriteCond %{QUERY_STRING} ^action=logout [NC]
RewriteRule ^/?(?:index\.php)?$ /forum/index.php [L,NC,R=301,QSA]
If you want a silent redirect (internal rewrite), just remove R=301 flag

How to change my url

I have this url
http://example.com/profile.php?u=78
I wanted to changed it to be like this
http://example.com/78/
How would I do that?
Please Help
Thanks in advance
You can use this .htaccess in your root directory:
RewriteEngine on
RewriteRule ^(\d+)/?$ /profile.php?u=$1 [L]
RewriteCond %{QUERY_STRING} ^u=(\d+)$
RewriteRule ^profile.php$ /%1/? [R=302,L]
Change [R=302,L] to [R=301,L] when that work well
Try this to rewrite http://example.com/profile.php?u=78 into http://example.com/78/:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^(\w+)=(\w+)$
RewriteRule ^profile.php$ /%2/
RewriteRule (.*) $1? [R=permanent]
Line-by-line explanation:
Turn on rewriting functionality
Specify the condition to make sure the query string is in the form of foo=bar for the following rules to apply.
Rewrite profile.php?foo=bar into /bar/?foo=bar
Remove all query strings that may still be appended to the new URL like /bar/?foo=bar/. This rule essentially substitute the entire path (.*) with itself ($1), and emptying the query string (?). [R=permanent] performs a permanent redirect (301).
Also, as previously commented, please ensure that http://example.com/78/ is a valid URL.

Set up of conditional redirect in htaccess

I've been asked to make an existing web site multi-language.
In preparation for this I have had to move all existing pages from /path/page to /en/path/page
To maintain any existing incoming links I now need to set up an htaccess redirect to send any requests from their original urls to the new /en/path/page urls but I'm having trouble getting this to work.
This is what I currently have;
RewriteCond %{REQUEST_URI} !^/en$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
Which I think is meant to check the requested URI and if it doesn't begin with /en then prepend /en onto the requested URI... but I'm obviously mistaken since it doesn't work.
Any help appreciated. Thank you.
UPDATE.
Since this is an ExpressionEngine site and there is an additional rule to remove the index.php portion of the URL here are both rules
# Rewrite for new language based urls
# This is to try and get all current pages going to /en/(old url) with a 301 redirect
RewriteCond %{REQUEST_URI} !^/en(/.*)?$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
# Removes index.php
RewriteCond $1 !\.(gif|jpe?g|png|ico)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
I have also tried this with the language rewrite after the index.php one. I'm still getting stuck in loops.
What it does is, checking whether the URI is not exactly /en, since the $ indicates the end of the string right after en.
Try this, it checks whether the URI is not exactly /en or /en/ or doesn't start with /en/, and if that's the case it will prepend /en/:
RewriteCond %{REQUEST_URI} !^/en(/.*)?$
RewriteRule ^(.*)$ /en/$1 [R=301,L]
update Considering the other rules you have in your .htaccess file, it is necessary to have the language rule not match again for the following internal redirect to /index.php..., otherwise you'll end up with an endless loop.
There may be better ways to prevent this, however the first thing that comes to my mind would be checking for index.php in the first condition:
RewriteCond %{REQUEST_URI} !^/(index\.php|en)(/.*)?$
So this will cause the rule not to apply after the internal redirect. But be careful, this solves the problem for this specific case only in which the internal redirect goes to index.php!

RewriteRule [L] still changing the url

I found myself with this problem, which is driving me a little bit crazy. I use apache's mod_rewrite for pretty URLs and I need to use dynamic subdomains in the site. Everything is great and all the server has de wildcards. I use the next code on my .htacess:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.mysite.com
RewriteCond %{HTTP_HOST} ([^.]+).mysite.com [NC]
RewriteRule ^(.*)$ http://www.mysite.com/%1 [L]
The only problem is, even if I use the [L] flag the url of the site change to http://mysite.com/subdomain. What i want is the url to be like http://subdomain.mysite.com
The link mysite.com/subdomain is a dynamic url and is solved with another rule with the following code:
RewriteRule ^([A-Za-z]+)$ filter.php?type=subdomain&subdomain=$1
Any help would be appreciated
If you specify an external URL (which changing the subdomain does), a header redirect will take place. I don't think you can prevent that. But why not skip that step altogether, and use the second RewriteRule straight away?
I can't test this right now, but something like
RewriteCond %{HTTP_HOST} !^www.mysite.com
RewriteCond %{HTTP_HOST} ([^.]+).mysite.com [NC]
RewriteRule ^(.*)$ filter.php?type=subdomain&subdomain=$1
should work.

Resources