WordPress.org

Ready to get started?Download WordPress

Forums

Polylang
Permalinks migration (15 posts)

  1. deadbird
    Member
    Posted 1 year ago #

    Hi.
    I've been using polylang for a while now, it's an amazing tool! But i'm facing a problem.
    Until now, I've been using "index.php?p=number" permalink structure. Now I'd link to use "%postname%", but when I switch from the old structure to the new one, everything goes 404 :'(

    Could you help?

    Thanks a lot ;)

    http://wordpress.org/extend/plugins/polylang/

  2. deadbird
    Member
    Posted 1 year ago #

    BTW, my website is http://deadbird.fr

  3. zuffap
    Member
    Posted 1 year ago #

    Hi, I think I found the issue.

    I also like the Polylang module and I also ran into 404 errors when using %postname% pretty permalinks. Because I did not find a solution to this on Internet, just a couple of similar reports, I had to sit down and debuge the module myself and I think I found it.

    The issue is caused by rewrite rules added for language category, tag = "language_rewrite_rules".
    Even though they ARE processed (removed) by the Polylang module (polylang.php, function rewrite_rules, lines 371-372: if (($current_filter = current_filter()) == 'language_rewrite_rules') return array();), this processing is too late and it is not executed when the language-related rewrite rules are being created (wp-includes/rewrite.php, function rewrite_rules, line 1580: $rules = apply_filters($permastructname . '_rewrite_rules', $rules);).

    This is because the Polylang prepare_rewrite_rules() function that actually adds the filter, is called too late (Polylang constructor, line 88, add_action('wp_loaded', array(&$this, 'prepare_rewrite_rules'), 20);)

    So my suggested quick fix is to move the add_filter("language_rewrite_rules") to the end of the init method (Polylang::init(), line 335: add this line: add_filter('language_rewrite_rules', array(&$this, 'rewrite_rules'));
    )

    Then redundant adding in prepare_rewrite_rules() can be removed, so the enumeration on line 359 can be changed to:

    foreach ($types as $type)
      if ($type != 'language')
        add_filter($type . '_rewrite_rules', array(&$this, 'rewrite_rules'));

    Works for me.

  4. zuffap
    Member
    Posted 1 year ago #

    Some more experiments revealed, that most probably the whole Polylang::prepare_rewrite_rules() must be called from init(), otherwise localized homepage (and other pages requiring language code) will not work.

    So the final fix suggestion is to add the mentioned call at the end of the init() function of the Polylang object, so the tail should look like:

    add_permastruct('language', $options['rewrite'] ? '%language%' : 'language/%language%', version_compare($GLOBALS['wp_version'], '3.4' , '<') ? false : array('with_front' => false));
    
    $this->prepare_rewrite_rules();
    }
  5. flakerimi
    Member
    Posted 1 year ago #

    @zuffap, I tested your fix and it works but it breaks somehow custom post types, I will inspect more later but just to let you know.

  6. zuffap
    Member
    Posted 1 year ago #

    Might be, I'm pretty new to WordPress and the site I'm working on has no custom post types, so I haven't noticed it does not work.
    Probably the rewrite rules creation must be split - some of them must be created earlier (like the language_rewrite_rules) and some laters, especially rules related to custom post types as these are most probably not yet initialized in the init() phase.
    Please, try to investigate and let me know.
    Thanks.

  7. deadbird
    Member
    Posted 1 year ago #

    Wow zuffap, you did an amazing job debugging the whole thing, thanks a lot!

  8. Chouby
    Member
    Plugin Author

    Posted 1 year ago #

    In WordPress rewrite rules are not created each time WordPress loads because it is a very expensive task. Instead, they are created on demand and stored in the database.

    So it is a priori not possible to know when the rewrite rules are created but there are good practices to follow.

    Typically, the rules are created when you change your permalinks structure. Some plugins (as Polylang) need to modify the rewrite rules and so do this at plugin activation and de-activation. Other (or same) plugins need to modify these rules per user action (typically if you create a custom post type or a custom taxonomy with a plugin, or if you change some 'url' options in Polylang).

    In all these cases, Polylang should work well.

    However some plugins "flush rewrite rules" in an "init" action each time WordPress loads. This is very bad practice as stated in the codex. And such plugins will break Polylang (and probably other plugins which need to act on rewrite rules).

    So I would be interested to know if you can detect if your problem is the result of a conflict with a plugin (or maybe the theme).

  9. zuffap
    Member
    Posted 1 year ago #

    Well, this issue occurred each time I manually triggered the rebuild of rewrite rules (via Permalinks -> Save), meaning the incorrect language_rewrite_rules breaking the %postname% permalink rewrite rule was stored in the database, so I assume it's not the problem of flushing rewrite rules in init of any m module, but I can have a look.

    Perhaps better tuning of order of calls to add_filter can be done to get the desired result.

    Have you been able to reproduce the issue?

  10. Chouby
    Member
    Plugin Author

    Posted 1 year ago #

    No I don't reproduce. But I mentionned above a known issue. I can't apply your proposal because it will break compatibility with plugins which register custom post types and taxonomies. That's why I am interested to know if you are able to identify a conflict with another plugin or your theme.

  11. zuffap
    Member
    Posted 1 year ago #

    I found the the guilty module - it's WordPress e-commerce (http://wordpress.org/extend/plugins/wp-e-commerce/)!
    There, in the file marketplace.php on line 300 there is:
    add_action( 'init', array(&$this, 'flush_rewrite'), 999 );
    Commenting out this line made the Polylang work smoothly without any (my) additional intervention. Now the question is, if this flushing is needed for the e-commerce module to work, or not, but that's a question for different forum, different topic.

    On the other hand - now that we know there are such "treacherous" modules out there doing such things, could you think about amending the Polylang module to survive in such environment? I find it very helpful (great job Chouby, BTW!) and more people could use in combination with not-that-codex-compliant modules...

  12. Chouby
    Member
    Plugin Author

    Posted 1 year ago #

    I did not find this file and this instruction in the latest version of wp-ecommerce. So maybe, updating could solve your issue.

  13. deadbird
    Member
    Posted 1 year ago #

    Hi.
    Back to the original problem!

    Updating didn't solve anything. Migrating permalinks to %postname% makes deadbird.fr redirect to deadbird.fr/en/, which leads to a 404.

    do you want me to send you the list of the plugins I use beside polylang? In this case please send me an email at [deadbird99 %at% gmail.com].

  14. zuffap
    Member
    Posted 1 year ago #

    try to search for a construct like this: $wp_rewrite->flush_rules(); in all plugins and the current theme source code and if you find it, try to disable it, just as I did in the wp-e-commerce plugin.
    And, by the way, I'm using it's Lite version (http://wordpress.org/extend/plugins/wordpress-ecommerce/) which is unfortunately up to date (no update is possible) and CONTAINS this rules flushing...

  15. Chouby
    Member
    Plugin Author

    Posted 1 year ago #

    Before diving into the code, the best is to de-activate all plugins but Polylang and then activate them one by one to detect the conflict. The conflict may alos come from the theme. Then if you come with a plugin name that we can download, we should be able to help.

Topic Closed

This topic has been closed to new replies.

About this Plugin

About this Topic

Tags