1

Our site uses the following schema:

example.com/channels/channel_name?v=videoId

I would like to be able to capture the channel_name directory and rewrite it as a query variable like so:

example.com/channels?watch=channel_name&v=videoId

What would be the correct .htaccess syntax preserving any trailing parameter variables while masking the transformation from the user?

MrWhite
  • 12,647
  • 4
  • 29
  • 41
  • Is "channel_name" a physical directory on the filesystem (I assume not)? How are your URLs currently routed/handled? `/channels?watch=channel_name&v=videoId` - this isn't really a valid endpoint (there is no file here) - what is the underlying filesystem path that accepts the request? – MrWhite Jan 27 '20 at 18:16
  • No: The underlying physical directory structure is: `example.com/channels`. It is assumed that any directory after channels, e.g.; "channel_name", are virtual. Hence, something along the lines of: `RewriteRule ^channels/(.*)$ /channels/ [R=302,NC,L]` – lincolnberryiii Jan 27 '20 at 18:25
  • So how is your system currently routing requests of the form `/channels/channel_name?v=videoId`? You must already have some rewrites in place, otherwise that URL-path is not valid? Any new rewrites you require need to work with your existing rewrites. – MrWhite Jan 27 '20 at 18:28
  • I have no such routing requests in place at the moment. I don't know how to do both, i.e.; Redirect from a virtual directory of `/channels/channel_name/` to just the "base" directory `/channels/` while appending any given directory "channel_name" as a query variable assigned to `?watch=channel_name`. That's where I'm stumped! – lincolnberryiii Jan 27 '20 at 18:42
  • It's just that you stated "Our site uses the following schema"? Is that the URL you are currently linking to? Going back to my first comment... "what is the underlying filesystem path that will process requests of the form `/channels?watch=channel_name&v=videoId`? If `/channels` is a physical directory then rewriting to that URL makes no sense. eg. Are you using PHP, do you have an `/channels/front-controller.php` script that will handle this request? – MrWhite Jan 27 '20 at 19:10
  • Yes. In the meantime, I have a workaround solution: `RewriteRule ^channels/(.*)$ /watch/?channel=$1 [R=302,NC,QSA,L]` In this case, `example.com/channels/channel_name?v=videoId` gets rewritten as `example.com/watch/?channel=channel_name&v=videoId`. This will suffice if I can't get a better solution to my original question. – lincolnberryiii Jan 27 '20 at 19:10

1 Answers1

1
example.com/channels?watch=channel_name&v=videoId

It's still unclear exactly what you are trying to do here since you've not identified the script (ie. front-controller) that would actually handle this request. What is the name of the script that reads the URL parameters and ultimately serves the content?

You've stated that /channels is a physical directory on the filesystem (so the URL-path would need to at least end in a slash, ie. /channels/?watch=channel_name&v=videoId) so this isn't strictly a valid end-point for a rewrite (as it still requires additional rewriting to script that would actually do something). It would need to be of the form (assuming PHP):

example.com/channels/front-controller.php?watch=channel_name&v=videoId

Where front-controller.php is the script that actually handles the request (ie. the front-controller).

In order to achieve this rewrite (from /channels/channel_name?v=videoId) you could do something like the following in the root .htaccess file:

RewriteEngine On

RewriteCond %{QUERY_STRING} ^(v=videoId)$
RewriteRule ^channels/([\w]+)$ channels/front-controller.php?watch=$1&%1 [QSA,L]

Where the channel_name can consist of the characters a-z, A-Z, 0-9 and _ (which covers your example URL).

/channels/front-controller.php is the script that actually handles the request and returns the content. Although, this can be anywhere, it doesn't need to be in the /channels directory (in fact, it would be easier if it wasn't - to avoid potential conflicts).

%1 is a backreference to the captured group in the preceding CondPattern. ie. the value v=videoId. Saves repetition.

This is an internal rewrite - the URL that the user sees stays as /channels/channel_name?v=videoId.

I have a workaround solution:

RewriteRule ^channels/(.*)$ /watch/?channel=$1 [R=302,NC,QSA,L]

Although this is an external redirect - the URL the user sees is modified to the new URL. What file handles the request in this case? Is the v=videoId parameter not required?

MrWhite
  • 12,647
  • 4
  • 29
  • 41