I am trying to do the following:
Rewrite the URL structure of my WordPress installation so that a language field is in there. E.g. http://www.mydomain.com/lang/
I want to then take the input from /lang/ and use it to display the appropriate content. E.g. if lang is ‘en’ I will take custom fields in English and display the theme in English.
Here is what I have so far:
<?php
function add_directory_rewrite() {
global $wp_rewrite;
add_rewrite_tag('%lang%', '(.+)');
add_rewrite_rule('^/(.+)/', 'index.php?p=$matches[1]&lang=$matches[2]', 'top');
add_permastruct('lang', '%lang%');
}
add_action( 'init', 'add_directory_rewrite' );
?>
This works as far as getting the language but the problem I am facing is now the_permalink() has “/%lang%/” where /en/ is supposed to be or /fr/ or /de/ or whatever language. To add more detail my permalink structure is /%lang%/%category%/%postname%/ and lets say I have a category called food and a post with the title chicken, the_permalink will generate http://www.mydomain.com/%lang%/food/chicken/
Any idea what I’m doing wrong? Cheers.
You additionally need to add a function that will take the permalink that contains the erroneous ‘/%lang%/’ segment, and replace it with the appropriate default language for the post. Typically you can do this either by the
'pre_post_link'
filter, or the'post_link'
filter. If you use the former, you will be creating the permalink from scratch (totally custom urls that use nothing that core WP has to offer). If the latter is use, then you can filter the permalink after WP has done it’s magic, but before it is used on the site. Here is an example:You don’t mention it so I will. With your original solo function, you are gunna have a hard time if it is stand alone. The reason is because, though you have told the rewriter that a new url segment exists, you didn’t tell WordPress to expect it as a url param. Thus, even though you have some fancy code to rewrite the url and tell WordPress the fancy lang param, WordPress does not know that it should be looking for it, and thus ignores it. You need to add something like this to rectify that:
This will tell the
WP()
class that it needs to accept the'lang'
instead of just skipping over it. Then later you can do something like this to figure out that the current page sent as it’s language:Hope this helps.
EDIT
First I want to say, this is an absolute travesty that language urls are not natively supported by WordPress. I have honestly never needed to do this, but most of my clients are not international companies, with international needs. I will be submitting something to WordPress in code form to solve this in a later version, but as of now, you will need a plugin like the one I have created below.
So I did a lot of investigation to make this happen. After a short conversation with the questioner, if found that my solution was incomplete. Naturally, I started digging. What seems like it should be an otherwise mediocre task, has turned out to be a VERY-not-mediocre task. The short version is, WordPress simply does not want you to insert extra parts of the url, in the middle or beginning of the url, on every url. You can easily do this with post urls ONLY with the above code, but anything more (pages, attachments, author pages, etc…) you must do something special. You can also add parts to the end of the url (endpoints), but even that is complicated.
I have worked with the WordPress rewriter extensively in the past and present, and I have what is considered Expert knowledge on the topic. Despite that, it still took me 4-5 hours to write something that will allow you to prepend a language indicator to all urls, that can then later be used to determine what language the page should be displayed in, regardless of page type. There is one catch, that I think is acceptable. You must know and specify exactly what language prefixes you want to support. I don’t foresee this as a problem for anyone who would make use of this, but none-the-less, it is a limitation, simply because of the way that the rewrite engine works.
At long last, here is a plugin that you can use to accomplish this. I works on a barebone WP install, with a WooTheme as the theme. If you have other third party plugins installed, there is a possibility that this will not work for all their urls, depending on how they added their rewrite rules. In the short term, I will probably be converting this to a plugin for WP, and getting it up on WordPress.org, but that is several days away, at least. Here is a working prototype of the code in plugin form. Create a new directory in your plugins folder (something like /wp-content/plugins/lou-lang), and then paste this code in a php file inside that folder (something like /wp-content/plugins/lou-lang/lou-lang.php). Then activate the plugin, via your admin dashboard, which will be labeled ‘Loushou Language URLs’.
CODE:
By default, the only language code supported by this plugin is
'en'
. Obviously you need more than just that. Thus, once you have installed the plugin, you can add some code to your<theme>/functions.php
file that looks something like this, to add the remainders.Once you have both installed the plugin and defined your custom languages, then you have one final step. You must save your permalinks. To do this from the admin, go to: Settings -> Permalinks -> Save Changes (button). After all of this, you should be good to go!
Hopefully this helps someone, and hopefully I can block out some time to get this up on wp.org.
The question is old but.. I was working on a lightweight solution for multi-language site and i came across the same problem. There is no easy way to do it with built-in WordPress functions. However (like mentioned by user1254824) there is a really easy trick to achieve it.
You can intercept the
$_SERVER['REQUEST_URI']
global var, extract the /lang/ part and remove it before WordPress parsing. WordPress will serve you the regular page, but now you have your lang parameter in a var.Then, you can also use filters to automatically rewrite all your links.
PS : The code need to be in a plugin. It won’t work in your template php files.
I stumbled across this post while looking for a solution to put a language tag in front of the url path. While the wp_rewrite-solution is pretty much solid it kind of didn’t work for my purpose (e.g. not having the language tag in front for the default language etc.).
So I took a closer look at the qTranslate-plugin and after I while I figured out that it uses a very simple and elegant solution:
Basically it does two things:
(Obviously) It changes all the WordPress generated links (e.g. post_link, post_type_link, page_link etc.) to include the correct language tag in the url.
Instead of manipulating complex rewrite rules to have wordpress accept and correctly handle the language tag, it just hooks into “plugins_loaded” (that’s right before WordPress tries to parse the request) and manipulates
$_SERVER['REQUEST_URI']
by cleaning out the language tag.So if you e.g. call http://www.example.com/en/myurlpath WordPress only “sees” http://www.example.com/myurlpath.
$_SERVER['REQUEST_URI'] = "/en/myurlpath"
before the manipulation.$_SERVER['REQUEST_URI'] = "/myurlpath"
after the manipulation.This way your only “job” is to clean up any urls before WordPress is parsing them.