views:

121

answers:

2

I'm going crazy. The only thing I want to do is add these rules to the site that I'm developing:

fastigheter-spanien/x    property/X&lang=sv
fastigheter-usa/x    property/X&lang=sv
properties-spain/X    property/X&lang=en
properties-usa/X    property/X&lang=en

Where X is the name of the post. These are all custom post types. The reason I ended up with this situation is that I use multiple languages but wanted the client not having to create more than one post for each article (they have a lot of options and images, having to re-publish them is practically out of the question). I've looked into creating rewrite_rules in functions.php and also modifiying the .htaccess file but haven't been able to get it to work. These rewrites are so simple they shouldn't need to use any functions. Can't I just adapt the .htaccess file?

Tried

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_URI} !^/fastigheter-spanien/([^\./]+)
RewriteCond %{REQUEST_URI} !^/fastigheter-usa/([^\./]+)
RewriteCond %{REQUEST_URI} !^/properties-spain/([^\./]+)
RewriteCond %{REQUEST_URI} !^/properties-usa/([^\./]+)

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

RewriteRule ^fastigheter-spanien/([^\./]+)$ property/$1 [L]
RewriteRule ^fastigheter-usa/([^\./]+)$ property/$1 [L]
RewriteRule ^properties-spain/([^\./]+)$ property/$1&lang=sv [L]
RewriteRule ^properties-usa/([^\./]+)$ property/$1&lang=sv [L]

Which just gives me a 404. Any ideas?

+1  A: 

If all else fails with the .htaccess file then there is a alternative solution to hooking in "by plugin"

Here is a snippet from one of my plug-ins.

<?php 
function fancy_url_hook($var='REQUEST_URI')
{
    if (!in_array($var, array('REQUEST_URI', 'PATH_INFO'))) $var = 'REQUEST_URI';
    $req = $_SERVER[$var];

    if (($var != 'PATH_INFO') && isset($_SERVER['PATH_INFO'])) {
        fancy_url_hook('PATH_INFO');
    }
    $explodeURL = array_slice(explode('/',$req),1,5);

    global $language;

    switch($explodeURL) {
        case 'fastigheter-spanien': $url = 'sv'; break;
        case 'fastigheter-usa': $url = 'sv'; break;
        case 'properties-spain': $url = 'en'; break;
        case 'properties-usa': $url = 'en'; break;
    }

    $language = $url;

}

function source_function()
{
    global $language;
    $_GET['lang'] = $language;

}

add_action('init', 'fancy_url_hook');
add_action('init', 'source_function');
?>

Although, it will need some editing and it has to directly hook in from a "plugin". So a plug-in may be necessary.

Although, have you tried disabling all plug-in after editing the .htaccess file?

Anraiki
Sorry, gave up this issue. It's too big of a puzzle to solve the mixup between WordPress' own rewrites, WPML's rewrites and my rewrites to be worth the while. Thanks for your help.
Staffan Estberg
Aw thats unfortunate. MAybe one day it will just come as a epiphany
Anraiki
+2  A: 

Your rewrites should be working correctly, but WordPress doesn't see your modifications. The reason for this is that WordPress reads from $_SERVER['REQUEST_URI'], which will always contain the original request URI, instead of the resulting one from the mod_rewrite operations.

I'm not familiar with actually using WordPress, but I have looked at some of the source code for some other questions, and it seems it will also attempt to use $_SERVER['PATH_INFO'], if it's provided. Consequently, you can try this:

AcceptPathInfo On
RewriteEngine On
RewriteBase /

RewriteRule ^fastigheter-(spanien|usa)/([^\./]+)$ property/$2&lang=sv
RewriteRule ^properties-(spain|usa)/([^\./]+)$    property/$2&lang=en

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* /index.php/$0 [L]

I find that using PATH_INFO is problematic though (and typically won't work in a per-directory context, although I don't think that I've determined why yet), and generally recommend against it.

Your other option involves working a bit on the PHP side as well. You can do something similar to what Anraiki suggested, or you can just tell $_SERVER['REQUEST_URI'] to be what you're expecting.

If mod_rewrite performs a redirection, the REQUEST_URI as the module sees it is stored in the server's REDIRECT_URL variable. So, adjusting the rewrite ruleset a bit, we can do this:

RewriteEngine On
RewriteBase /

# Force L on these rules to cause the REQUEST_URI to be changed (so that
# REDIRECT_URL will end up with the rewritten value we want)
RewriteRule ^fastigheter-(spanien|usa)/([^\./]+)$ property/$2&lang=sv [L]
RewriteRule ^properties-(spain|usa)/([^\./]+)$    property/$2&lang=en [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Then, somewhere early on in the WordPress processing (such as in index.php, since you shouldn't likely need to update that file with subsequent WordPress releases), you could do the following:

if (!empty($_SERVER['REDIRECT_URL']))
    $_SERVER['REQUEST_URI'] = $_SERVER['REDIRECT_URL'];

There may very well be a way to define your behaviour in WordPress using the permalink settings themselves, since it does iterate over that rule list in parsing the request, but I'm not entirely clear on the details of this as I've never used it myself. If this is possible, I would consider it the recommended way of handling this situation, but either way hopefully one of these options should get things working for you.

Tim Stone
Sorry, gave up this issue. It's too big of a puzzle to solve the mixup between WordPress' own rewrites, WPML's rewrites and my rewrites to be worth the while. Thanks for your help.
Staffan Estberg