Just dipping my toes into the world of .htaccess URL rewriting for the first time, and fallen at the first hurdle. However am sure I'm missing something obvious...:)
My htaccess currently looks like this, which is a Wordpress install running from /wordpress but re-written to appear at the top level of the domain:
php_value short_open_tag 1
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) wordpress/$2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ wordpress/$2 [L]
RewriteRule . index.php [L]
</IfModule>
I want to add a rewrite rule to take anyone accessing:
/publication-details.php?id=xxx (where xxx is a number
to
/publications/pub-xxx/
I thought something like this would work:
RewriteRule ^publication-details.php?id=([0-9]+) /publications/pub-$1 [NC]
But I've tried that as a rule but it's not working - no matter where I order it in the existing rules. Trying to visit /publication-details.php just gets a 404 (Apache default). If I try /whatever (ie no extension in the URL) I get the Wordpress 404.
What am I missing?!
Thanks in advance.
Edit your Permalink to %postname%
add_filter( 'rewrite_rules_array','my_insert_rewrite_rules' );
add_action( 'wp_loaded','my_flush_rules' );
function my_insert_rewrite_rules( $rules )
{
$newrules = array();
$newrules['([^/]+)/publication/pub-([^/])/?$'] = add_rewrite_rule( '([^/]+)/publication/pub-([^/])?$', 'index.php?pagename=$matches[1]&pub-id=$matches[3]', 'top' );
return $newrules + $rules;
}
add_action( 'wp_loaded','my_flush_rules' );
// flush_rules() if our rules are not yet included
function my_flush_rules(){
$rules = get_option( 'rewrite_rules' );
if (! isset( $rules['([^/]+)/publication/pub-([^/])/?$'] )) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
}
RewriteRule only works on the URI, not the Query String.
To do what you're trying to, you need a RewriteCond (=Condition) to check the Query String, e.g.
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule ^publication-details.php /publications/pub-%1? [R=302,L]
The RewriteCond is a condition for the following RewriteRule. Note that it's %1 in the Rule, not $1, to use a match from a Condition ($1 is only for matches in the Rule). I've added a single quotation mark at the end to disable the addition of the Query String, otherwise it would redirect to /publications/pub-12345?id=12345.
Related
I have some error on wordpress site after installing WPML and make some translations, this error make 500 error on my site
error: AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace., referer https://mexter.reasavings.top/uk/nakopichuvalni-vodonagrivachi/
I found some answers but not now how can i do/change this
my .htaccess has next lines maybe i need change this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# BEGIN WordPress
# Директивы (строки) между `BEGIN WordPress` и `END WordPress`
# созданы автоматически и подлежат изменению только через фильтры WordPress.
# Сделанные вручную изменения между этими маркерами будут перезаписаны.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^ru/wp-login.php /wp-login.php [QSA,L]
RewriteRule ^uk/wp-login.php /wp-login.php [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
On wordpress site with WPML has fix in functions.php from theme
need add this lines:
add_filter('mod_rewrite_rules', 'fix_rewritebase');
function fix_rewritebase($rules){
$home_root = parse_url(home_url());
if ( isset( $home_root['path'] ) ) {
$home_root = trailingslashit($home_root['path']);
} else {
$home_root = '/';
}
$wpml_root = parse_url(get_option('home'));
if ( isset( $wpml_root['path'] ) ) {
$wpml_root = trailingslashit($wpml_root['path']);
} else {
$wpml_root = '/';
}
$rules = str_replace("RewriteBase $home_root", "RewriteBase $wpml_root", $rules);
$rules = str_replace("RewriteRule . $home_root", "RewriteRule . $wpml_root", $rules);
return $rules;
}
I have created a rule to rewrite urls croziere/{example}/{example} to pages named with a combernation of the contents of the last two slashes. Eg croziere/destination/uk to index.php?pagename=destination-uk.
function custom_rewrite_rule() {
add_rewrite_rule('^croaziere/([^/]*)/([^/]*)/?','/index.php? page_name=$matches[1]-$matches[2]','top');
}
add_action('init', 'custom_rewrite_rule', 10, 0);
here's how the htaccess looks :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /travel/
RewriteRule ^index\.php$ - [L]
RewriteRule ^croaziere/([^/]*)/([^/]*)/? /travel/index.php?pagename=$matches[1]-$matches[2] [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /travel/index.php [L]
</IfModule>
and here is the rewrite debug :
The correct regex is:
croziere/([a-z]*)/([a-z]*)
which for croziere/destination/uk will return
array(
0 => croziere/destination/uk
1 => destination
2 => uk
)
update, if you want to combine matches into a single word....confirmed working assume you have a pagename with a structure something-something and the page exists. btw make sure you flush the rewrite rules rather than adding directly to htaccess, if you are you need to properly escape the appropriate characters.
function custom_rewrite_rule() {
add_rewrite_rule('croaziere/([a-z]*)/([a-z]*)','/index.php?pagename=$1-$2','top');
}
add_action('init', 'custom_rewrite_rule');
I have two domains on the same server pulling from the same wordpress database, I would like anytime someone types in sitea.com/random to be redirected to siteb.com/random. I am able to redirect the homepage with
RewriteCond %{HTTP_HOST} ^www2\.sitea\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.www2\.sitea\.com$
RewriteRule ^/?$ "http\:\/\/www2\.siteb\.com" [R=301,L]
However this does not forward any URL with a trailing URL (ex. sitea.com/random/). I have used the wildcard option to forward everything to the new domain, however since the sites are pulling from the same IP, it runs into a redirect loop.
Any help would be appreciated. Thanks in advance!
Try this:
RewriteCond %{HTTP_HOST} ^www2\.sitea\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.www2\.sitea\.com$ [NC]
RewriteRule ^(.*)$ http://www2.siteb.com/$1 [R=301,L]
Unfortunately it was not that easy, but I did end up finding an answer. In wp-config.php I added and ran the function
function curPageURL() {
$pageURL = 'http';
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
}
return $pageURL;
}
$redirect = str_replace("www2.", "", curPageURL());
$remove_http_root = str_replace('http://', '', $redirect);
$split_url_array = explode('/', $remove_http_root );
if($split_url_array[0] == "olddomain.com"){
header("Location: http://www2.newdomain.com/$split_url_array[1]");
die();
}
and then I added a simple redirect for the homepage in .htaccess
RewriteCond %{HTTP_HOST} ^www2\.olddomain\.com [OR]
RewriteCond %{HTTP_HOST} ^www\.www2\.olddomain\.com
RewriteRule ^/?$ "http\:\/\/www2\.newdomain\.com" [R=301,L]
Hopefully this will help someone else. And maybe someone will come up with a cleaner way to do it.
I've a database-table with some user generated content. Each content-element is available via /my-url/project/the-projects-name . The items are NO wordpress posts. I've created an index-script where I redirect to when such an URL is called. The script then extracts the projects-name, put it in a variable and includes a page-template.
My page and the project-data are displayed well, but wordpress throws a 404-state for the requested website as well as setting the title to "Not Found!". How can I fake wordpress the output??
My htaccess which redirects to my index-projects.php-script:
RewriteCond %{REQUEST_URI} ^/my-url/project/(.*)
RewriteRule . /index-project.php [L]
my index-project.php:
ob_start();
define('WP_USE_THEMES', true);
$path = explode('/', $_SERVER['REQUEST_URI']);
while(empty($path[0]))
array_shift($path);
while(empty($path[count($path)-1]))
array_pop ($path);
if(count($path) >= 3 && !empty($path[2])) {
$postFound = false; // use this param to define if requested post was found in DB
$post_name = $path[2]; // get the post name from url
$args = parse_url($post_name);
$slug = $args['path']; // extract the post slug from post name
if(!empty($slug)) {
$wp_did_header = true;
$_GET['page_id'] = SOME_ID_OF_MY_WP_PAGE;
$_GET['main_page'] = 'page-project';
require_once( dirname(__FILE__) . '/wp-load.php' );
wp();
include('./wp-content/themes/my-theme/page-project.php');
}
}
RewriteRule ^/my-url/project/(.*) /index-project.php [L]
RewriteRule ^/index-project.php - [L]
and make sure you put it about the WP rules in your htaccess
Wordpress still throws an 404. The page is correctly loaded and the content is "redirected" to my index-project.php but WP still returns the 404-header to the browser:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^my-url/project/(.*) /index-project.php [L]
RewriteRule ^/index-project.php - [L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
I'm a .htaccess nOOb, but I think this is the best way to do it.
I need to make wordpress change the '/' into '#' in the url. The structure goes like:
http://thewebsite/pageid/sub_pageid and the desired effect would be http://thewebsite/pagid#sub_pageid . I've tried few rules I found on-line, but each one of them have failed. I believe its because I have those rules applied to it. There is only one page I have subpages for and it's the only one that needs rewriting. After the redirect I want jquery to scroll down to the anchor.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /thewebsite/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /thewebsite/index.php
</IfModule>
# END WordPress
I've tried RewriteRule ^page/ page# [NE] but I've failed. I've tried many others, but no effect. Hope someone had this problem before and just knows, or can explain why I fail.
Thanks!
If you are just trying to rewrite it for a single page, try:
RewriteRule [page\_id]\/(.*) /page_id#$1 [NE,R=301]
That should be all you need for a specific page id or string. NE means 'noescape,' allowing you to rewrite the hash (#) symbol.
For any page id:
RewriteRule ([0-9]+)\/(.*) /$2#$1 [NE,R=301]
Try this following code if not necessary skip the rewrite contidion download/.php ,make sure that you have to put a 404 file in your domain folder
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule (.*) index.php
RewriteCond %{SCRIPT_FILENAME} -f
RewriteCond %{SCRIPT_FILENAME} .*\.php|/$
RewriteCond %{SCRIPT_FILENAME} !download\.php
RewriteRule !/ index.php
ErrorDocument 401 /401.html
Hope it helps you
Ok,
Since I'm a .htaccess-lame I decided to use jQuery to solve my problem. I used .attr() to replace the original attribute 'href'. I've managed to change the links to subpages with:
$(function(){
$('#menu_on_HOME a').each(function(i){
var atitle = $(this).attr("href");
var strRep = atitle;
n = strRep.lastIndexOf('/'); //finds the last occurence of '/' to replace with '#'
if (n >= 0 && n + strRep.length >= strRep.length) {
strRep = strRep.substring(0, n) + "#" + strRep.substring(n + 1, n + strRep.length); // this is where magic happens
}
$(this).attr("href", strRep); //here is where I replace the original attribute 'href'
});
});
The function above sends me to page#subpage where PAGE contains the content of all subpages and clicking on the menu_on_HOME link goes straight to subpage anchor. Moreover, on the actual PAGE i have internal links to subpages (the content can be editable via cms as a page) but I didn't need to go deeper into subpage but rather get the desired anchor, so I used ScrollTo :
$(function(){
$('menu_on_PAGE a').each(function(i){
var atitle = $(this).attr("href");
var strRep = atitle;
n = strRep.lastIndexOf('/');
var name;
if (n >= 0 && n + strRep.length >= strRep.length) {
name = strRep.substring(n + 1, n + strRep.length);
strRep = strRep.substring(0, n) + "#" + name;
$(this).click(function(event){
var scroller = '#content a[name=' + name + ' ]'; //point to the anchor
$(window).scrollTo(scroller,{duration:1500});
});
}
$(this).attr("href", strRep);
});
});
$(window)._scrollable();
I don't know how 'right' or 'wrong' the solution is, however it works for me flawlessly :)