REQUEST_FILENAME without extension in RewriteCond - .htaccess

Is there any mode_rewrite variable like {REQUEST_FILENAME} but without the file extension?
The following works but I need to change my image naming:
RewriteCond %{REQUEST_FILENAME}.webp -f
RewriteRule \.(jpe?g|png)$ %{REQUEST_FILENAME}.webp [NC,L]
But now i need to change my image naming from: "image.jpg.webp" to "image_jpg.webp".
I need help with the new RewriteCond and RewriteRule in order to rewrite "image.jpg" to "image_jpg.webp" if the webp image exists.

Just capture value in RewriteRule and use it in RewriteCond:
RewriteCond %{REQUEST_URI} ^(.*/)([^/]+)\.(jpe?g|png)$ [NC]
RewriteCond %{DOCUMENT_ROOT}%1%2_%3.webp -f
RewriteRule ^ %1%2_%3.webp [L]

Related

htaccess redirecting to the wrong page when using multiple rewriterules

I have a htaccess file which looks like the following:
Options -Indexes
RewriteEngine On
# no php extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
# only allow rewriting to paths that dont exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# example.com/username
RewriteRule ^([\w\d_\-]+)/?$ profile.php?uid=$1 [L,QSA]
# example.com/username/$tab
RewriteRule ^([\w\d_\-]+)\/([\w]+)/?$ profile.php?uid=$1&tab=$2
# example.com/listen/$id
RewriteRule ^listen\/([\w\d_\-]+)?\/?([\w\d_\-]+)?$ track.php?id=$1&secret=$2 [L,QSA]
The way it is supposed to work is to redirect any URL looking like these:
1. example.com/example points to profile.php?id=example
or
2. example.com/example/tab points to profile.php?id=example&tab=tab
3. example.com/listen/example points to track.php?id=example
or
4. example.com/listen/example/code points to track.php?id=example&secret=code
The problem is that sometimes, a link which looks like the third one will point to the profile page. However, what's weirder, is that if example has a dash in it, it will point to the right place. This shouldn't be happening because my regex is matching after listen.
All help is appreciated.
Both of your listen/ rules should appear before other rules and moreover 2 RewriteCond are only being applied to next immediate RewriteRule.
You may use these rules to replace all of your code:
Options -Indexes
RewriteEngine On
# only allow rewriting to paths that don't exist
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# example.com/listen/$id
RewriteRule ^listen/([\w-]+)/?$ track.php?id=$1 [L,QSA,NC]
# example.com/listen/$id/secret
RewriteRule ^listen/([\w-]+)/([\w-]+)/?$ track.php?id=$1&secret=$2 [L,QSA,NC]
# no php extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
# example.com/username
RewriteRule ^([\w-]+)/?$ profile.php?uid=$1 [L,QSA]
# example.com/username/$tab
RewriteRule ^([\w-]+)/([\w-]+)/?$ profile.php?uid=$1&tab=$2 [L,QSA]
Also note that \w means [a-zA-Z0-9_] so no need to add \d_ in character class.

Rewrite rule in htaccess is not working

Here are the .htaccess rules:
RewriteEngine On
RewriteRule ^([^/]*)$ content.php?seourl=$1 [L]
RewriteRule ^pdf/([^/]*)$ content-single.php?seourl=$1 [L]
RewriteRule ^browsepdf$ browse.php [L]
RewriteRule ^browsepdf-([^/]*)$ browse.php?page=$1 [L]
RewriteRule ^download/([^/]*)$ download.php?pdf=$1 [L]
RewriteRule ^sitemap.xml$ xmlsitemap.php [L]
Options -Indexes
Here every URL is pointing to content.php?seourl=$1, even css, js and image files.
Here are some example URLs I need,
http://example.com/sjskjfsk21
http://example.com/asfasfasf43sf
http://example.com/pdf/fhfdhdh3432aaf
http://example.com/pdf/aisfyiahm2faf3
http://example.com/browsepdf
http://example.com/browsepdf-1
http://example.com/browsepdf-2
http://example.com/download/fjaskfjalsk3rs
http://example.com/download/usaydiy7aisydi
http://example.com/sitemap.xml
Can anyone please fix the .htaccess file.
Here every url is pointing to "content.php?seourl=$1"
Because your first (generic) rule catches all the requests. You need to change the order so you have the most specific rules first, and the most generic (catch-all) rules at the end. In your case you just need to move the first rule to the end. For example:
RewriteRule ^pdf/([^/]*)$ content-single.php?seourl=$1 [L]
RewriteRule ^browsepdf$ browse.php [L]
RewriteRule ^browsepdf-([^/]*)$ browse.php?page=$1 [L]
RewriteRule ^download/([^/]*)$ download.php?pdf=$1 [L]
RewriteRule ^sitemap\.xml$ xmlsitemap.php [L]
RewriteRule ^([^/]*)$ content.php?seourl=$1 [L]
NB: I backslash-escaped the dot in sitemap.xml to match a literal dot, otherwise it matches any character.
even css, js and image files.
You can make an exception for these static resources at the beginning of your file, before the existing directives. For example:
RewriteRule \.(js|css|png|jpg|gif)$ - [L]
For any URL that ends in any of the stated file extensions then stop processing the current mod_rewrite rules.
Alternatively (although perhaps marginally less efficient), you can prevent processing of requests for files that exist. Again, this goes before your existing mod_rewrite directives. For example:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
However, this must now check every request for the existence of a file on the filesystem that maps to the request. (It could also be combined with the above rule if required.)
UPDATE: Bringing this together, we have:
# Exclude any existing files from being rewritten
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Specific rewrites
RewriteRule ^pdf/([^/]*)$ content-single.php?seourl=$1 [L]
RewriteRule ^browsepdf$ browse.php [L]
RewriteRule ^browsepdf-([^/]*)$ browse.php?page=$1 [L]
RewriteRule ^download/([^/]*)$ download.php?pdf=$1 [L]
RewriteRule ^sitemap\.xml$ xmlsitemap.php [L]
# Any other requests for the form "/<anything>"
RewriteRule ^([^/]*)$ content.php?seourl=$1 [L]

How to use .htaccess to remove filename and only show parameters

My website page what I am recently working on is mydomain.com/page.php?cat=cover&brand=Nokia.
I want to display the url something like this -
mydomain.com/cover/nokia
Meaning I don't want to show the page name i.e. page.php and hide the parameter names as well. Also the last parameter is optional.
If somebody can help me doing this, will be a great help.
Thanks
You can use these rules in root .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ page.php?cat=$1&brand=$2 [L,QSA]
RewriteRule ^([^/]+)/?$ page.php?cat=$1 [L,QSA]

Htaccess how to invert extension and name

I tried to invert the name and the extension of a requested file, but unsuccesfully.
RewriteRule ^(.*)\.(.*)$ $2.$1
I tried that, but is not working.
Try:
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule ^(.*)([^/]+)\.([^/]+)$ /$1$3.$2 [L]

same path of url but pointing to different directories

Im trying to redirect this,
www.example.com/about expect to matched with docs/about.html
www.example.com/register expect to matched with mod/register.php
RewriteCond %{REQUEST_URI} !\.+$
RewriteRule ^([^\.][a-z]+)$ docs/$1.html [L]
RewriteRule ^([^\.][a-z]+)$ mod/$1.php [L]
The first rewrite rule works great,
but the second rewrite rule won't work, it keeps showing 404 error.
As long as you don't have the same file in both places (e.g. /docs/foo.html and /mod/foo.php, you can do a check against the destination first before you rewrite:
# check for docs/.html first
RewriteCond %{REQUEST_URI} ^/([a-z]+)$
RewriteCond %{DOCUMENT_ROOT}/docs/%1.html -f
RewriteRule ^ /docs/%1.html [L]
# If not .html, then check for mod/.php
RewriteCond %{REQUEST_URI} ^/([a-z]+)$
RewriteCond %{DOCUMENT_ROOT}/mod/%1.php -f
RewriteRule ^ /mod/%1.php [L]

Resources