form and substance of communication



The extremely useful qTranslate plugin for WordPress can translate the same blog in multiple languages, including the content and interface elements. Customization is one of its key features: according to the browser language or by explicit administration setting, the plugin chooses and displays the appropriate translation for texts, excerpts and page titles.

However, the author is willing to implement permalink translation in future versions, and at the moment we still need to install the qTranslateSlug unofficial patch to get also slugs in specific languages.

The primary code implies manual adding of a function in sidebar.php or in another template file to generate the language select code, so I’ve wrapped everything in a widget traced from the normal qTranslate one:

class qTranslateslugWidget extends WP_Widget {
	function qTranslateslugWidget() {
		$widget_ops = array('classname' => 'widget_qtranslateslug', 'description' => __('Allows your visitors to choose a Language.','qtranslate') );
		$this->WP_Widget('qtranslateslug', 'qTranslate slug widget', $widget_ops);
	function widget($args, $instance) {
		echo $before_widget;
		$title = empty($instance['title']) ? __('Language', 'qtranslate') : apply_filters('widget_title', $instance['title']);
		$hide_title = empty($instance['hide-title']) ? false : 'on';
		$type = $instance['type'];
		if($type!='text'&&$type!='image'&&$type!='both'&&$type!='dropdown') $type='text';
		if($hide_title!='on') { echo $before_title . $title . $after_title; };
		qTranslateSlug_generateLanguageSelectCode($type, $this->id);
		echo $after_widget;
	function update($new_instance, $old_instance) {
		$instance = $old_instance;
		$instance['title'] = $new_instance['title'];
		$instance['hide-title'] = $new_instance['hide-title'];
		$instance['type'] = $new_instance['type'];
		return $instance;
	function form($instance) {
		$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'hide-title' => false, 'type' => 'text' ) );
		$title = $instance['title'];
		$hide_title = $instance['hide-title'];
		$type = $instance['type'];
		<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:', 'qtranslate'); ?> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
		<p><label for="<?php echo $this->get_field_id('hide-title'); ?>"><?php _e('Hide Title:', 'qtranslate'); ?> <input type="checkbox" id="<?php echo $this->get_field_id('hide-title'); ?>" name="<?php echo $this->get_field_name('hide-title'); ?>" <?php echo ($hide_title=='on')?'checked="checked"':''; ?>/></label></p>
		<p><?php _e('Display:', 'qtranslate'); ?></p>
		<p><label for="<?php echo $this->get_field_id('type'); ?>1"><input type="radio" name="<?php echo $this->get_field_name('type'); ?>" id="<?php echo $this->get_field_id('type'); ?>1" value="text"<?php echo ($type=='text')?' checked="checked"':'' ?>/> <?php _e('Text only', 'qtranslate'); ?></label></p>
		<p><label for="<?php echo $this->get_field_id('type'); ?>2"><input type="radio" name="<?php echo $this->get_field_name('type'); ?>" id="<?php echo $this->get_field_id('type'); ?>2" value="image"<?php echo ($type=='image')?' checked="checked"':'' ?>/> <?php _e('Image only', 'qtranslate'); ?></label></p>
		<p><label for="<?php echo $this->get_field_id('type'); ?>3"><input type="radio" name="<?php echo $this->get_field_name('type'); ?>" id="<?php echo $this->get_field_id('type'); ?>3" value="both"<?php echo ($type=='both')?' checked="checked"':'' ?>/> <?php _e('Text and Image', 'qtranslate'); ?></label></p>
		<p><label for="<?php echo $this->get_field_id('type'); ?>4"><input type="radio" name="<?php echo $this->get_field_name('type'); ?>" id="<?php echo $this->get_field_id('type'); ?>4" value="dropdown"<?php echo ($type=='dropdown')?' checked="checked"':'' ?>/> <?php _e('Dropdown Box', 'qtranslate'); ?></label></p>
function qtranslug_widget_init() {
add_action('widgets_init', 'qtranslug_widget_init');


plugin in the WordPress directory



  1. Can you give some idiot proof guide how to use this. Say I have a fresh qtranslate and I just added your plug. I create a page which:
    is in 2 languages: en, de
    on the bottom of the edit page screen I add ‘rugs’ and ‘teppiche’ in certain fields.

    With link structure$lang$/
    I try to run and it returns 404

  2. I believe there is something wrong with permalinks in the original qtranslateslug, I have experienced the same problem. You could find a more detailed documentation in the qTranslate support forum,
    but hey, you are already registered there!

    First of all, try to put the post ID in your permalink structure.

  3. Hello,

    I get a error when i try to activate te plugin:

    Plugin could not be activated because it triggered a fatal error.
    atal error: Cannot redeclare qtrans_widget_init() (previously declared in /../../public_html/wp-content/plugins/qtranslate/qtranslate_widget.php:128) in /../../public_html/wp-content/plugins/qtranslate-slug-with-widget/qtranslate-slug-with-widget.php on line 878

  4. HiHo,
    first i want to thank you for your plugin .
    And second, you probably anticipate, i have a question.
    Am I right that your plugin produces a translation of a certain URL/permalink?
    If im right i got an issue with it.
    Can you tell me what permalink settings should be taken to make it work?
    regards axel

  5. 3dolab 7 Oct 2010 Reply

    Thank you, but in all truth the hardcoding was already done, I’ve only improved the plugin and made it available to everyone in the WP directory.

    With normal qTranslate, URLs are:

    This plugin translates the page/post name (slug) of permalinks:

    (but it doesn’t remove the pre-path or pre-domain code of qTranslate)
    The slugs in each enabled language can be set in the edit panel.

    I’m able to get it work with ID numbers in the permalink structure:

    I would recommend to try the latest 0.3 version where the widget name and db table name creation have been fixed.

    PS: amazing site, and the shoots are even better!
    I guess that I have to restyle soon my design, a bit more elegant like yours…
    I hope to have been helpful

  6. thomas 9 Nov 2010 Reply

    I got myself a problem:
    with the url it works,
    but with it breaks into
    that trailing slash is making it break.

    • 3dolab 29 Nov 2010

      Hmmm after some investigation I’ve been able to reproduce the problem, but not exactly the same:
      assuming english as secondary language, works as expected, while redirects to and displays the page in the default language.
      If you meant that, I believe the plugin needs to be improved a little further; otherwise I guess we should somehow review our URL rewrite rules.
      I’m going to post an update as soon as possible.

  7. just tested it on a production site and i’m impressed! it used the qtranslate titles unto slugs automagically!

    thanks 🙂

  8. How would I embed the widget into my theme header as I currently do with the qTranslate call echo qtrans_generateLanguageSelectCode ?

    • 3dolab 21 Jan 2011

      It’s more or less the same: simply use

  9. There seems to be a bug concerning the slug for a static homepage. After editing the frontpage the slug is set with double slashes. Other users seem to have the same error, see

    Any suggestions on how to fix this? Thanks

    • 3dolab 17 Feb 2011

      Thanks for your report!
      the bug was at line 419, last rows of the qTranslateSlug_page_link function:
      $link = implode('/',$linkParts);
      now it’s fixed in the 0.4 version by replacing that line with:
      if ($i == -1){
      $link = $linkParts[$i];
      else {
      $link = implode('/',$linkParts);

      so the slug of the homepage should not get that double slash.
      I hope it’s solved in all its variants…

  10. I did some tests with the updated 0.4 version and the bug is gone. Great work and thank you for the quick response!

  11. This plugin is just what I needed. I have installed and tested it and it woks for permalinks of posts and not with permalinks of pages. My permalinks are defined as /%postname%. Do you think you can help me?

    Also, I have a question: How is it possible to create a redirect every request from for example /slug to /en/slug to avoid duplicate content?


  12. Hello! thank you for this great plugin. I develop many hotel websites, and having the slug in many languages is extremely important. I had the initial problem with the /%post_id%/%postname% now its ok. Again, thank you for the great job! greetings from Morocco.

  13. Jean C. 8 Mar 2011 Reply

    I installed gTranslateSlug and set some pages with slugs in french and english. Everything was perfect. After editing titles in posts, slugs weren’t working anymore. When I’m in french, it links to /en/with_french_slug/ and i get a 404. When i’m in english, it links to (root)/english_slug/ and i get a 404…

  14. Hi.
    First of all, thanks for this plugin, it works perfectly.
    Do you have any idea in witch way i can customize it so the slug fields could be auto-filled by the post name. Do you know what i mean ? Basicly, i’m workibg with french, and English. So, each time a create a page, i’ve got 2 page name, let’s say “About” for english and “A propos” for French. So the slug i need, are about for english, and a-propos for french. Currently, i’ writing down the 2 lugs on your plugin, so i would like to know if there is a way to make this automatic.


  15. Firstly, thanks for great plugin!

    Ditto Miha’s problem. It seems to work if I put /%post_id%/%postname but then it adds post ids to my URLS for my posts which I really don’t want.

    Your help is greatly appreciated! Thanks!

  16. Hello,

    I’m currently trying your plugin on my wordpress installation and i have a problem with it.

    I can’t make it working, for example :

    I create a “Page” called :
    – “Références” in french
    – “Showcase” in english

    If i customize the slug in each language, if i use a special one different from the default one, i got a 404 error.

    My permalink is set to custom : /%post_id%/%postname%

    i use the last release on the plugin (same for the qtranslate plugin and wordpress version)

    Thanks for your help !


  17. ChrisR 6 Apr 2011 Reply

    Thanks for this qTranslate Goodie. Together with META I wish this to be part of future qTranslate versions. I like to write down some WP 3.1.1 in debug mode & your plugin 0.4 notices:

    Notice: Undefined variable: q_config in /wp-content/plugins/qtranslate-slug-with-widget/qtranslate-slug-with-widget.php on line 184
    Notice: clean_url is deprecated since version 3.0! Use esc_url() instead. in /wp-includes/functions.php on line 3303

    The plugin generated 494 characters of unexpected output during activation. If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin.

  18. Jorge Orejel 14 Apr 2011 Reply

    No soporta HTML ???

  19. 3dolab 5 May 2011 Reply

    To everybody having problems with permalinks, IDs, custom slugs, WordPress version higher than 3…
    it’s sad, but we have to wait the latest qTranslate version 3, it should natively support everything you need.

    Anyway, I didn’t try WPML but it looks really promising!

  20. Hello!

    Firstly, I would like to say thank you for the plugin. It is great and working like a charm for me.

    I have just one problem though. It is not working correctly with the plugin Contact Form 7. In German (my primary language) it works perfectly, but in English the messages do not appear correctly.

    In English, the message is sent correctly, but I get a “page is not found” error message. The same happens if someone enters incorrect data, such as an incorrect email address.

    I am sure that I just need to make a couple of changes in the code to correct this issue, but can’t find where.

    Can you help me?

    THANK YOU!!!

    • 3dolab 11 Jul 2011

      Hi, I don’t precisely know how the Contact Form 7 plugin works, but I think you have to edit that, in order to make it compatible with translations, and not vice versa.
      Does the problem occur with basic qTranslate (no slug translation) as well?

      Anyway, it seems it’s not a slug thing: I guess the form submission (its action property) is actually bypassing the translation check so the resulting URL will miss the language code (did you see? /contact instead of /en/contact) and redirect to a 404 page not found.

      There is a filter in the Contact Form /includes/classes.php file, at function form_html()
      $url = wpcf7_get_request_uri();
      if ( $frag = strstr( $url, '#' ) )
      $url = substr( $url, 0, -strlen( $frag ) );
      $url .= '#' . $this->unit_tag;
      $url = apply_filters( 'wpcf7_form_action_url', $url );
      $enctype = apply_filters( 'wpcf7_form_enctype', '' );
      $class = apply_filters( 'wpcf7_form_class_attr', 'wpcf7-form' );

      You should be able to add_filter('wpcf7_form_action_url', url_lang_switch'); in your theme’s functions.php and then process (or append / prepend, depending on your permalink structure) the URL with something like:
      function url_lang_switch($url){
      global $post, $q_config;
      if (isset($q_config)) {
      // stripped down qTranslate_converturl
      switch($q_config['url_mode']) {
      case QT_URL_PATH: // pre url
      // might already have language information
      if(!preg_match("#^([a-z]{2})/#i",$pag,$match)) {
      if(qtrans_isEnabled($q_config['language'])) {
      $url = $q_config['language'].'/'.$url;
      case QT_URL_DOMAIN: // pre domain
      if (!preg_match("#^([a-z]{2}).#i",$pag,$match)) {
      if(qtrans_isEnabled($q_config['language'])) {
      $url = $q_config['language'].'.'.$url;
      // found language information, remove it
      $pag = preg_replace("/".$match[1]."\./i","",$pag, 1);
      default: // query
      if(!preg_match("#(&|\?)lang=([^&\#]+)#i",$pag,$match)) {
      if(qtrans_isEnabled($q_config['language'])) {
      $url .= '?lang='.$q_config['language'];
      return $url;

      But it’s just a sketch, it’s still untested. Check the function qTranslateSlug_urlAddLang($link,$lang,”, $home); for further infos.

  21. Hey, thanks for your great plugin!

    I wanted to ask if you could give me some hints how to make it work with a custom post_type – in addition to the type ‘page’ I have the type ‘portfolio’ in my theme, which I cant get to work!

    Any help would be appreciated.

  22. Thank you for your great plugin!

    It works really nice for my site (WordPress 3.2.1). But we have some problem with page. Slug of page doesnt work, it only works with post. :(. Can you help us to solve that problem?

  23. hi, work this plugin with pages?
    i installed it, set up slugs and have this:
    when i switch to non-default lang – en > it works
    but when i switch back, it leaves en slug in url, which produce 404 not found

    Any ideas?

  24. Replace the SQL UNION for the search ….

    SELECT ID, post_name, post_parent FROM wp_posts LEFT JOIN wp_qtranslate_slug ON wp_posts.ID=wp_qtranslate_slug.qts_id WHERE wp_qtranslate_slug.qts_slug = ‘about-us’ AND wp_qtranslate_slug.qts_type = 2 AND wp_qtranslate_slug.qts_lang = ‘en’ AND (wp_posts.post_name = ‘about-us’ AND (wp_posts.post_type = ‘page’ OR wp_posts.post_type = ‘attachment’))

  25. Hey i have a question for you people, how did you manage to remove the post ID from the URL?



    The plugin that you created WORKS AWESOME but i need to remove the id and I notice that you managed to do so, but when i use the plugin “qtranslate-slug-with-widget.0.4” it keeps displaying the post ID on the URL.

    Thanks for any help that you can give me on this one.

    • 3dolab 17 Sep 2011

      Sorry but I managed to remove the ID from the URL because now I’m running WPML, and not qTranslate

  26. Does this plugin depend on .htaccess or does it work with any web server?

    I’m about to install this on NginX.

    • 3dolab 7 Sep 2011

      Now I’m not sure if qTranslate does use any URL rewriting, but this plugin only filters functions and queries so it should work on any server

  27. That’s helpful to know. Thank you!

  28. Hi, I’m having a problem. If I delete an article and create a new one with the name/slug, when I try to acces to this new article I get a 404, as slug still make reference to the deleted article. Any idea of how can I solve this?

  29. Any idea of how can I delete the slug of a post when I delete it?

    • 3dolab 17 Sep 2011

      While implementing category slug translation in version 0.5 (thanks to Matteo Plebani) and support for custom post types, I’ve tried to meet your needs by adding an action to the “delete_post” hook. Unfortunately, I’m unable to test it since I’m not using qTranslate anymore: please consider support and further development of this slug translation plugin as being actually almost discontinued.
      However, if you’re still interested, you can give a try to the latest version. If you could report that it works, we all will obviously appreciate.

  30. @Andres, it seems to me that you have to look at your Trash area. Emptying it cold help.

  31. Hey, version 0.5 works with qTranslate v2.5.24 (the latest version). I have tested it only with pages slug,… this is perfect for me. Thanks a lot!
    Permalinks should be set to /%post_id%/%postname%

    One thing should be modified now, and that is language chooser. It should always point to homepage. If not and visitor click to a flag when on anyother page (not homepage) this produces Not found error.

    Please any one know how can this be solved?
    That way we could finaly have qTranslate with multilingual slug 🙂

  32. My apologize… homepage is not just a homepage, there is more in the background…
    I went to qtranslate_widget.php file and changed if(is_404()) $url = get_option('home'); else $url = ' '; to if(is_404()) $url = get_option('home'); else $url = get_home_url(); what actually do what I want, but then internal site links have no Pre-Path in URL anymore.

    Some developers help would be highly appreciated.

  33. No, I delete it from the trash, but they are still there in the data base. Thanks anyway.

  34. Hi, I made this change instead of what you did to delete the slug:

    add_action(‘admin_init’, ‘codex_init’);
    function codex_init() {
    if (current_user_can(‘delete_posts’)) add_action(‘delete_post’, ‘codex_sync’, 10);

    function codex_sync($pid) {
    global $wpdb;
    if ($wpdb->get_var($wpdb->prepare(“SELECT qts_id FROM {$wpdb->prefix}qtranslate_slug WHERE qts_id = %d”, $pid))) {
    return $wpdb->query($wpdb->prepare(“DELETE FROM {$wpdb->prefix}qtranslate_slug WHERE qts_id = %d”, $pid));
    return true;

    I hope it could help to anothers.

  35. Hi!

    First of all thank you for creating this great plugin. Translated slugs are a must have!

    However I have a very specific case now, where I am struggeling. I am using

    qtranslate & qtranslate slug widget & custom post types (a product page)

    On normal pages and posts the widget displays correctly – however on the custom post types it does not work. I understand that you do not support the widget – but I need someone to point me in the right direction of where to look for help (or I need a developer that can make it work). Anyway – I am happy to spend some money on this and feed the code back into the community!

    Thanks for your help


  36. Hi!
    There is an error in the qtranslate-slug-with-widget.php file on line 849: rename the function’s name from save_qTranslateSlug_category_fileds to save_qTranslateSlug_category_fields

  37. massimo 10 Nov 2011 Reply

    hi, the qtranslate slug 0.5 non working … becouse in my categories the texbox url slug remain null.

  38. The solution from Jurij was also (the only) solution for the 404 errors on slugs.
    In fact, If a guest would come to the home page, they would already be in the right language or choose one at that time.
    So to me it does not make sence to switch languages when navigating between pages and posts.

  39. friendly 27 Nov 2011 Reply

    smile found the problem when saving and the category URL slug for each language is still empty.

    simply look for the line:

    function save_qTranslateSlug_category_fileds( $term_id ) {

    and replace it by this line:

    function save_qTranslateSlug_category_fields( $term_id ) {

    that will fix it 🙂

  40. This is really an excellent plugin, slug support is an important part for a multi-lingual website. It’s a shame you don’t develop it any longer, but I can understand why if you’re using WPML instead (we also use WPML for our own site and prefer it to qTranslate, but qTranslate is more suitable for some projects).

    The plugin works great, I’m not seeing any IDs, it switches between pages in different languages. I do, however, have the issue, that the “original” qTranslate URL is still accesible. For example, the english URL is:

    The new French slug is:

    The “original” URL can still be reached at:

    This means that there will be two different URLs with the same content, which isn’t so good for SEO. I just wanted to check whether this is the correct behaviour, or if something is wrong with our system.

    I presume there just isn’t a redirect for the original URL, when visiting it directly?

    Realise you don’t support the plugin any longer, but would be happy if you had time to reply!

  41. Arihant 24 Dec 2011 Reply

    Hey..Awesome plugin.
    I am using hindi as my secondary language.
    I have problem
    When i insert the following text in the slug in hindi
    “अन्दर देखो”
    it is converted to the word below on clicking update
    the link in the browser however is displays correctly but the canonical url shows the link below


    but the browser displays it correctly like belowअन्दर देखो

    Is there a way to include support for unicode characters

  42. Arihant 24 Dec 2011 Reply

    I also have the same question as @Karl mentioned just above my previous comment.

  43. I installed this plugin and it works if I manually change every slug. But how do I get the slug to automatically change based on title.

    For example


  44. Hi there, call me stupid but there is a post that mentiones slug translation for categories as well. Where do I do it? I get still english categories in a German post. This is the last issue forf me to solve before I can get startet.


  45. Hi, thanks for the nice plug!

    I use version 0.5, but I’m having the double slash problem whenever I chose from the main nav menu the static page that is selected as the front page.

    try clicking the first menu item (in any language)

    When editing the page, the noneditable part of the permalink has the double slash, so no way to get rid of…

    Any ideas (or additional info that I’d need to give)?

  46. Lisa, did you set permalinks to custom as
    in settings / permalinks
    also check when you edit a page, at the very bottom, there it says “qtranslate slug translation”, edit entries for all languages

    hope it helps,

  47. Dankeschön Großartige Info.

  48. I’m looking to implement this plugin within a custom post type.
    It doesn’t work if I set my custom post type even if I don’t ‘rewrite’ the slug.

    Anyone have any tips / solutions?

  49. One of my clients ran into a problem with 0.6. The ID parameter in qTranslateSlug_category_link would sometimes be an object, instead of an int. As near as I can work out, this has something to do with the way taxonomy terms work. I can’t spend more time figuring it out, but the following quick and dirty patch fixes the problem:

    @@ -620,6 +620,9 @@ function getParentCategoriesSlugTranslation($link, $catid, $lang) {

    function qTranslateSlug_category_link($link, $id){
    + if(is_object($id)) {
    + $id = $id->term_id;
    + }
    //TODO: implement it!
    global $wpdb, $q_config, $qts_use_language, $wp_query;
    $lang = ($qts_use_language === null)?$q_config[‘language’]:$qts_use_language;

  50. Mario Sebastiani 12 May 2012 Reply

    I’ve just updated to the last version and I get this error on all my categories: “mysql_real_escape_string() expects parameter 1 to be string, object given in /htdocs/public/www/wp-includes/wp-db.php”. I’ve disabled qtranslateslug and it works again fine… Can you help me to resolve this issue? I really like your plugin…

  51. I had the same problem as Mario Sebastiani. I downgraded to the version 0.5 and everything is fine again.

  52. grumo64 16 May 2012 Reply

    Same probleme for me 🙁

  53. Same problem here…

  54. Visit the plugin’s wordpress support page and the solution is there

  55. @Sebastiani, @radgo, @grumo64, @CG: Bram posted a bugfix for this problem a few comments up.

    Not sure why the plugin author hasn’t applied this patch yet.

    • 3dolab 2 Jul 2012

      Sorry, priorities are:
      -site redesign
      -content update
      -plugin development
      and I still can’t find the time!!

  56. chiflon 18 Jul 2012 Reply
  57. Timo Elshof 21 Aug 2012 Reply


    How can How can I have displayed the country flags horizontal/side by side the right sidebar of my Twenty Eleven theme using Qtranslate-slug? Can somebody help me?

    Kind regards

  58. Alter Ego 20 Feb 2013 Reply


    The plugin works fine with posts slugs but, when it comes to pages, it doesn’t work properly (in fact, it doesn’t work).

    I have a site which is bilingual in Spanish/English, so it goes like this:





    So, as you can see, in pages, it only adds the ‘en’ prefix, but doesn’t use the translated slug, but the default language one, as it should be ‘/en/page-title/, instead of ‘/en/titulo-de-la-pagina’.

    Any hint on how could I solve it?


Leave a Reply

  • development diary