i'm currently working on a wordpress site that needs to have the option to be offered in french. i've found a way to make the theme work with the fr_FR po and mo files when i add a querystring variable l. i.e.
site.tld will yield the vanilla english site, while site.tld/?l=fr will activate the following code in my functions.php to serve the french translation:
<?php
// http://codex.wordpress.org/Plugin_API/Filter_Reference/locale
add_filter( 'locale', 'set_my_locale' );
function set_my_locale( $lang ) {
if ("fr" == substr(strtolower(trim(strip_tags(stripslashes($_GET['l'])))), 0, 2)) {
// set language to french
return "fr_FR";
} else {
// return original locale
return $lang;
}
}
?>
this setup is already working. my question is: how do i rewrite the url so instead of site.tld/?l=fr i can just prepend the folder structure with fr i.e. site.tld/fr/?
so like if there's a page site.tld/portoflio/autumn/ in english, site.tld/fr/portfolio/autumn/ will spit out the french one. i got this idea from the apple website, where the language is always prepended to the folder structure.
i can already make this happen with an external redirect in htaccess:
RewriteBase /
RewriteCond ^[a-z]{2}/
RewriteRule ^([a-z]{2})/(.*)$ /$2?l=$1 [R,L]
this works, but once i remove the R flag it serves the french-translated 404 not found isntead. i'm guessing what i did is messing-up with wordpress' rewrite rules because i need to use pretty permalinks. right now i'm set to use Month and name (/%year%/%monthnum%/%postname%/) in the admin general options.
my question is, how do i make wordpress ignore the /fr/ part and still serve the correct page/post/etc?
is this even possible? am i on the right track here? i need your help especially doing what's WISE and not just what's NICE. i tried this http://pmg.co/a-mostly-complete-guide-to-the-wordpress-rewrite-api but for the life of me i can't make it work. :/
UPDATE: ok, so here's some progress taking cue from #relu below:
i made sure my rules were canned from .htaccess
i then added the rules from #relu but in the following way, because Relu's always sent me to the same address without the /fr:
<?
// http://pmg.co/custom-wordpress-shortlinks
add_action( 'init', 'pmgtut_add_rewrites' );
function pmgtut_add_rewrites() {
add_rewrite_rule( '^([a-z]{2})/?$', 'index.php?l=$matches[1]', 'top' );
add_rewrite_rule( '^([a-z]{2})/(.*)$', 'index.php?l=$matches[1]&q=$matches[2]', 'top' );
}
add_filter( 'query_vars', 'pmgtut_query_vars', 10, 1 );
function pmgtut_query_vars( $vars ) {
$vars[] = 'l';
return $vars;
}
?>
now the /fr stays in the address bar, so that's a good thing, but two problems persist:
wordpress is serving me the main index page. seems like it's not using the &q=$matches[2] part of the rule; and
the locale still doesn't get set properly. i checked if the variable l is getting fed, so i added echo 'l: $l'; after $l = get_query_var('l'); and interestingly i get two echoes: one l: and another l: fr right after that. is the locale filter being run twice? seems like the first time it doesn't see the value of the queryvar, and then there seems to be a second time that it outputs l: with fr already in there.. at the end of the day the locale still doesn't get changed.
aaaah help.
FINAL UPDATE: in my last breath of frustration i searched again, and found this plugin qtranslate. does what i need. thanks y'all, esp to #relu's epic effort and stayin pow'r.
Add this to your functions.php
add_filter( 'rewrite_rules_array','my_insert_rewrite_rules' );
add_filter( 'query_vars','my_insert_query_vars' );
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['^([a-z]{2})/(.*)$'] ) ) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
}
// Adding a new rule
function my_insert_rewrite_rules( $rules )
{
$newrules = array();
$newrules['^([a-z]{2})/(.*)$'] = 'index.php?l=$matches[1]&q=$matches[2]';
return $newrules + $rules;
}
// Adding the l var so that WP recognizes it
function my_insert_query_vars( $vars )
{
array_push($vars, 'l');
return $vars;
}
Haven't tested this, it may need some tweaking, but this is the way to do it.
I've basically adapted the version found here.
It also registers the "l" query var so you can get it's value by calling: get_query_var
add_filter( 'locale', 'set_my_locale' );
function set_my_locale( $lang ) {
$l = get_query_var('l');
if ("fr" == $l) {
// set language to french
return "fr_FR";
} else {
// return original locale
return $lang;
}
}
UDATE: Ignore the above!
Remove the my_insert_query_vars() filter and replace it with:
function register_rewrite_tag() {
add_rewrite_tag('%l%', '([a-z]{2})');
}
add_action('init', 'register_rewrite_tag');
Here are also the updated rewrites for pages and posts, I've looked at WordPress' $wp_rewrite->rules and adapted them to fit this special case:
function pmgtut_add_rewrites() {
add_rewrite_rule( '^([a-z]{2})/?$', 'index.php?l=$matches[1]', 'top' );
add_rewrite_rule( '^([a-z]{2})/(.?.+?)(/[0-9]+)?/?$', 'index.php?l=$matches[1]&pagename=$matches[2]&page=$matches[3]', 'top' ); // Pages
add_rewrite_rule( '^([a-z]{2})/([^/]+)(/[0-9]+)?/?$', 'index.php?l=$matches[1]&name=$matches[2]&page=$matches[3]', 'top' ); // Posts
}
maybe out of topic but here's another rewrite rule for languages of the form; en_us/ or jp/
add_rewrite_rule( '^([a-z]{2}_[A-Z]{2}|^[a-z]{2})/?$', 'index.php?l=$matches[1]', 'top' );
Related
I am trying to follow the examples in the wordpress documentation about add_rewrite_rule and add_rewrite_tag.
I'm using a custom post type called "panel".
so the pages look like "site.com/panel/post-slug"
url queries work: for example I have 2:
var1 and testquery.
if I go to "/panel/test-page-auto/?var1=10"
And with var1 and testquery:
so what i want is, change the /panel/test-page-auto/?var1=10&testquery=Hi
-> /panel/test-page-auto/10/Hello
my code:
add_action('init', '__rewrite_tag_rule', 10, 0);
function __rewrite_tag_rule() {
$page_type = "^panel/";
add_rewrite_tag('%testquery%', '([^&]+)');
add_rewrite_tag('%var1%', '([^&]+)');
//Add rule
//panel/test-page-auto/10/edit
add_rewrite_rule(
$page_type."test-page-auto/([^/]*)/([^/]*)/?",
'index.php?pagename=test-page-auto&var1=$matches[1]&testquery=$matches[2]',
'top' );
//add rule for show
//panel/test-page-auto/10
add_rewrite_rule(
$page_type."test-page-auto/([^/]*)/?",
'index.php?pagename=test-page-auto&var1=$matches[1]&testquery=Hi',
'top' );
}
add_filter('query_vars', function($vars) {
$vars[] = "testquery";
$vars[] = "var1";
return $vars;
});
But it's not working.
when I try to put /panel/test-page-auto/10/Hi it just redirects me to /panel/test-page-auto and the queries are blank.
Can someone help me understand what I'm doing wrong?
I have already tried:
save permalinks after each change.
edit the rules in various ways.
test the links using the queries and they are working.
I want to add a simple custom Wordpress rewrite rule but somehow I don't get this working.
This URL
http://www.gewerbesteuer.de/steuer/muenchen
should call this
http://www.gewerbesteuer.de/index.php?pagename=gewerbesteuerhebesaetze&loc=muenchen.
So I want to call a page, which displays tax rates for a certain city, the city should be in the url as the last part.
Here is my code:
function custom_rewrite_tag() {
global $wp_rewrite;
add_rewrite_tag('%loc%', '([^&]+)');
add_rewrite_rule('steuer/([^/]+)',
'index.php?pagename=gewerbesteuerhebesaetze&loc=$matches[1]', 'top');
flush_rewrite_rules();
}
function query_vars($query_vars ) {
$query_vars[] = 'loc';
return $query_vars;
}
add_action('init', 'custom_rewrite_tag');
add_filter( 'query_vars', 'query_vars' );
The rewrite rule is working but the parameter (in this case loc) is not picked up. Even if I hardcode the rewrite rule with a certain city like
add_rewrite_rule('steuer/([^/]+)',
'index.php?pagename=gewerbesteuerhebesaetze&loc=muenchen', 'top');
it still doesen't pick up the value of the loc parameter. I also noticed that the $matches array is empty and doesn't contain any values.
I went through all the docs at wordpress and the questions here, but couldn't find the problem. Any ideas?
Thanks
Bernhard
Can you try adding this and see if this makes any difference?
Edited
I have changed the paramter in the rewrite rule from "pagename" to "page_id" - I am assuming its 2207 as thats what it said from looking at the body class on your website's page.
I also removed flush_rewrite_rules() from the custom_rewrite_rules_tags function, can you try this now then go to Options > Permalinks and re-save again.
function custom_rewrite_rules_tags() {
global $wp_rewrite;
add_rewrite_tag('%loc%', '([^&]+)');
add_rewrite_rule(
'steuer/([^/]+)',
'index.php?page_id=2207&loc=$matches[1]',
'top'
);
}
add_action('init', 'custom_rewrite_rules_tags');
function custom_query_vars($query_vars ) {
$query_vars[] = 'loc';
return $query_vars;
}
add_filter( 'query_vars', 'custom_query_vars' );
I have a problem I've encountered when trying to finish a project.
I have the current permalink structure set as /%postname%/
I made my own function on giving a prefix to posts only so my posts are rewritten as /{prefix}/%postname%/.
My problem is that I want to change the permalink of the pages as I did with the posts so my pages will have a prefix like /{prefix}/%pagename%/.
What I tried and didn't work:
Re-declare the PAGES post type and set a rewrite slug.
Tried adding a custom rewrite rule as a function but it didn't work:
$rewrite_rules += array('mycustomprefix/(.+?)/([0-9]+)/([^/]+)/([^/]+)/?$' =>'index.php?pagename=$matches[1]',
Is this possible? Are there any developers out there who encountered the same issue?
For anybody interested, I've fixed my issue in the following manner:
function change_author_permalinks() {
global $wp_rewrite;
// Change the value of the author permalink base to whatever you want here
$wp_rewrite->author_base = '';
// Change the value of the page permalink base to whatever you want here
$wp_rewrite->page_structure = 'static/%pagename%';
$wp_rewrite->flush_rules();
}
add_action('init','change_author_permalinks');
Hope this helps others as I couldn't find any help for this anywhere. For morer information on what you can change this way, check out http://codex.wordpress.org/Class_Reference/WP_Rewrite
Have you updated the permalinks structure after adding this rewrite to your functions.php ? It works for me :)
add_filter( 'page_rewrite_rules', 'customprefix_page_rewrite_rules' );
function customprefix_page_rewrite_rules( $rewrite_rules )
{
end( $rewrite_rules );
$last_pattern = key( $rewrite_rules );
$last_replacement = array_pop( $rewrite_rules );
$rewrite_rules += array(
'mycustomprefix/(.+?)/?$' => 'index.php?pagename=$matches[1]',
$last_pattern => $last_replacement,
);
return $rewrite_rules;
}
I found this solution working for me better... and it's also much cleaner code.
add_action( 'init', 'custom_page_rules' );
function custom_page_rules() {
global $wp_rewrite;
$wp_rewrite->page_structure = $wp_rewrite->root . 'your-page-prefix/%pagename%';
}
I found the code here: http://wpforce.com/change-wordpress-page-permalinks/
My WordPress site has a portfolio that is at www.mysite.com/portfolio/. The portfolio sections and items are administered through a custom plugin I created. I want to access the individual items like www.mysite.com/portfolio/my-cool-photo and have that put "my-cool-photo" into a query string like ?portfolio_item=my-cool-photo so I can read it from my code.
In the plugins activation PHP file I have this code:
function add_rewrite_rules($wp_rewrite) {
$new_rules = array(
'portfolio/(.+)/?$' => 'index.php?&portfolio_item=$1'
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules');
function query_vars($public_query_vars) {
$public_query_vars[] = "portfolio_item";
return $public_query_vars;
}
add_filter('query_vars', 'query_vars');
This adds the rewrite rule to the array OK. The problem is it's not doing anything. When I go to www.mysite.com/portfolio/testing/ I get the "This is somewhat embarrassing, isn’t it?" WordPress 404 error page. Obviously the redirect isn't working, so the query string won't be filled, but just to make sure I did this:
global $wp_query, $wp_rewrite;
if ($wp_rewrite->using_permalinks()) {
$searchKey = $wp_query->query_vars['portfolio_item'];
} else {
$searchKey = $_GET['portfolio_item'];
}
...and sure enough the query string isn't getting passed.
Is there something I'm missing?
After you update the WordPress rewrite rules, you need to flush them:
http://codex.wordpress.org/Function_Reference/flush_rewrite_rules
You can choose to flush with the $hard parameter true, and then you should be able to see your rewrite rules in the .htaccess file.
Here is the example rewriting url code. Hopefully this will help users.
In this url like http://www.domainname.com/test-page?urltags=ABCD is run as http://www.domainname.com/test-page/ABCD
<?php
function add_my_rule() {
global $wp;
$wp->add_query_var('tags');
add_rewrite_rule('test-page/([^/]*)','index.php?pagename=test-page&urltags=$matches[1]','top');
}
function add_my_tags() {
add_rewrite_tag('%urltags%', '([^&]+)');
}
add_action('init', 'add_my_rule');
add_action('init', 'add_my_tags', 10, 0);
?>
I am using 'Now Reading' plugin in a wordpress project. In plugin's sidebar template I am using this query:
while( have_books('status=read&orderby=finished&num=2') ) : the_book();
to select 2 books.
What parameter should I pass to make it random? I tried with 'order=rand' and 'rand=true' but it did not work.
Any help will be appreciated!
Thanks in advance..
A random function doesn't actually exist. I have used this code, in my themes functions.php to allow random order before - not sure if it'll work in this situation, but worth a try.
Add this to your themes functions.php file:
function query_random_posts($query) {
return query_posts($query . '&random=true');
}
class RandomPosts {
function orderby($orderby) {
if ( get_query_var('random') == 'true' )
return "RAND()";
else
return $orderby;
}
function register_query_var($vars) {
$vars[] = 'random';
return $vars;
}
}
add_filter( 'posts_orderby', array('RandomPosts', 'orderby') );
add_filter( 'query_vars', array('RandomPosts', 'register_query_var') );
Then try this in your sidebar file:
while( have_books('status=read&orderby=finished&num=2&random=true') ) : the_book();
If not, my only other suggestion would be to get the 10 latest books, add them all to a new array, and then shuffle that array. May be a bit bloated though.