Match exactly one URL segment with regex in Wordpress - php

I want to rewrite these URLs in Wordpress:
http://localhost/one/.../
http://localhost/one/...
Using the following code:
add_rewrite_tag('%my_test%','([^/]*)');
add_rewrite_rule(
'^one/([^/]*)/?',
'index.php?page_id=0&my_test=$matches[1]',
'top'
);
It works, but it also allows URLs like:
http://localhost/one/.../...
http://localhost/one/.../.../...
How can I rewrite only /one/.../ and /one/... URLs and return 404 for /one/.../.../ etc?

The '^one/([^/]*)/?', is matching /one/.../ and /one/... and /one/(nothing). Hovewer anything beyond that is ignored because the regex is not terminated. You need to add $ to the end. And you probably want to replace the * with a + if you don't want to match /one/(nothing) . So, '^one/([^/]+)/?$', should work.

Related

Wordpress rewrite rule for custom PHP page

I have created a PHP page which I'm using an include plugin for in wordpress.
So when I visit domain.com/kb it shows me the included PHP file which works fine.
I want to make the URL pretty so I tried adding this to the top of the php file:
add_rewrite_rule('^kb/([^/]*)/([^/]*)/?','index.php?page_id='.get_the_ID().'&category=$matches[1]&sequence=$matches[2]','top');
But when I visit domain.com/kb/123 is just removes the 123 and leaves domain.com/kb/
Ultimately, I want to be able to visit domain.com/kb/123/456 where I can read "123" and "456" as separate variables.
The current regex you have doesn't match kb/123, because it looks for a mandatory 2nd /. (marked in blue)
I'm gonna ignore that and go for your end-goal.
Going by this answer,
i've come up with the following solution:
function wpd_foo_rewrite_rule() {
add_rewrite_rule(
'^kb/(.*?)/([^/]*)',
'index.php?page_id='.get_the_ID().'&category=$matches[1]&sequence=$matches[2]',
'top'
);
}
add_action( 'init', 'wpd_foo_rewrite_rule' );
let's go over the regex -
that ?, in that context, means "lazy". match as few characters as possible until you hit the following char (/). (then, of course, we save it in a capture group).
Afterwards, let's deal with the 2nd parameter.
The following will take everything between kb/ and the 1st / (well, 1st after kb's) into the 1st capture group, (attention! the 1st / must exist, otherwise it isn't a match),
and everything after the 1st /, into the 2nd capture group.
this assumes you won't have any other "/" parameters (they'll all be in capture group 2) and that you won't have any query parameters (same thing).
if you want to utilize your "any char except /, that's fine too.
As a rule - never trust user input, always sanitize it. be on the lookout for ways to trick your plugin into loading files it shouldn't, inserting malicious data into storage (DB etc..), or querying data it shouldn't
btw - screenshots taken from regexr

Rewrite rule ignore what's in front

I would like to rewrite
http://www.example.com/a/b/c/d/S123
with endless virtual subdirectories (keywords) to
http://www.example.com/?id=123
But it seems my rule is only working for
http://www.example.com/S123 (without "subdirectories").
What is wrong on this rule?
^S(?:.+/)?(\d+)/?$
^S... means that your url segment STARTS with S which is true for /S123 and not for a/b/a/S123.
use this regex instead :
^.*S(?:.+/)?(\d+)/?$

RegExp to match a segment of a URL

I'm trying to use RegExp to match a segment of a URL.
The URL in question is this:
http://www.example.com/news/region/north-america/
As I need this regex for the WordPress URL Rewrite API, the subject will only be the path section of the URL:
news/region/north-america
In the above example I need to be able to extract the north-america portion of the path, however when pagination is used the path becomes something like this:
news/region/north-america/page/2
Where I still only need to extract the north-america portion.
The RegExp I've come up with is as follows:
^news/region/(.*?)/(.*?)?/?(.*?)?$
However this does not match for news/region/north-america only news/region/north-america/page/2
From what I can tell I need to make the trailing slash after north-america optional, but adding /? doesn't seem to work.
Try this:
preg_match('/news\/region\/(.*?)\//',"http://www.example.com/news/region/north-america/page/2",$matches);
the $matches[1] will give you the output. as "north-america".
You should match using this regex:
^news/region/([^/]+)
This will give you news/region/north-america even when URI becomes /news/region/north-america/page/2
georg's suggested rule work like a charm:
^news/region/(.*?)(?:/(.*?)/(.*?))?$
For those interested in the application of this regex, I used it in the WP Rewrite API to grab the custom taxonomy and page number (if present) and assign the relevant matches to the the WP re-write:
$newRules['news/region/(.?)(?:/(.?)/(.*?))?$']='index.php?region=$matches[1]&forcetemplate=news&paged=$matches[3]';

Grabbing a domain name from URL as a variable by htaccess

Imagine in my website I want to show some analytic about domains, working URL example of what I need:
http://whois.domaintools.com/google.com
As you see in the above URL, it's handling google.com as a variable and pass it to another page to process the given variable, that's exactly what I want.
So for detecting that kind of variable, here is my regex:
/^[a-zA-Z\d]+(?:-?[a-zA-Z\d])+\.[a-zA-Z]+$/
The above RegEx is simple and accepts everything like: google.com, so in my .htaccess file I have:
RewriteRule (^[a-zA-Z\d]+(?:-?[a-zA-Z\d])+\.[a-zA-Z]+$) modules/pages/page.php?domain=$1
The above rule do what I want, but it also redirects my homepage to page.php while there is nothing in the URL, forexample: http://mysitename.com is now being forwarded to page.php
How can I fix this?
Thanks in advance
It redirects also the base domain to page.php because of the regex. You are using the + on all places, the meaning of the plus is "Matches the preceding pattern element one or more times.". (http://en.wikipedia.org/wiki/Regular_expression) If you request the homepage, it redirects because all the elements are appearing zero times, like you defined in the regex.
Instead of the + you should define a minimum and a maximum amount of characters (so the zero occurrences are not evaluated). BTW, a quick search in google for "regex domain" will output a lot of results, which are tested. Use the following for example:
RewriteEngine on
RewriteRule (^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$) modules/pages/page.php?domain=$1
Reference:
Domain name validation with RegEx
Update 1:
If you want to use your own regex, exchange the last "+" with {2,}. The top-level domains have usually at least 2 characters.
RewriteEngine on
RewriteCond %{REQUEST_URI} !(\.html|\.php|\.pdf|\.gif|\.png|\.jpg|\|\.jpeg)$
RewriteRule (^[a-zA-Z\d]+(?:-?[a-zA-Z\d])+\.[a-zA-Z]{2,}$) modules/pages/page.php?domain=$1

PHP - How to add a pages title to the URL? And how to create a clean url using PHP

I was wondering how can I create clean urls using PHP. Do I do this all in PHP or do I need to use mod_rewrite in some way? Can someone explain this to me in laymans terms?
Here is my current url a element link and how it looks in the browser
http://www.example.com/members/1/posts/page.php?aid=123
But I want it to read the pages title.
http://www.example.com/members/1/posts/title-of-current-page/
First you need to generate "title-of-current-page" from PHP, using this function eg:
function google($string){
$string = strtolower($string);
$string = preg_replace('/[^a-zA-Z0-9]/i','-',$string);
$string = preg_replace("/(-){2,}/",'$1',$string);
return $string;
}
Second thing, you need to make a rewrite, but you should keep aid in form of "/123-title-of-current-page"
Rewrite would go something like this (I am ignoring your entire URL)
RewriteRule ^([0-9]+)-(.*?)$ page.php?aid=$1 [L,QSA]
You can do this using mod_rewrite:
You'll need to edit a file called .htaccess at the top level of your web folder. This is where you can specify certain settings to control the way Apache accesses items in this folder and below.
First things first. Let's turn on mod_rewrite: RewriteEngine On
RewriteRule ^([a-z]+)/([a-z\-]+)$ /$1/$2.php [L]
The rule matches any URL which is formed of lower case letters, followed by a /, then more lower case letters and/or hyphens, and appends .php to the end. It keeps track of anything wrapped in brackets () and refers to them later as $1 and $2, i.e. the first and second match. So if someone visits these URLs:
http://example.com/weblog/archive
it will be converted to following:
http://example.com/weblog/archive.php
You will find more details on :
http://wettone.com/code/clean-urls
You have to use a rewrite to direct all requests to an existing php file, otherwise you get all 404 not found errors because you are trying to get a page that simply is not there.
Unless you rewrite your 404 page to handle all requests and you definitely donĀ“t want to go there...

Categories