nginxurl-rewritingvbulletinxenforo

nginx rewrites vBulletin to XenForo


There is a similar question here but the answer does not work, and the official answer from XenForo does not work either. Apparently they had an issue with forums moving from a /forums setup to the root domain level, but the fix for that does not work.

Old link https://www.twcenter.net/forums/member.php?10263-Gaius-Baltar

New link https://twcenter.net/members/gaius-baltar.10263/

Old link https://www.twcenter.net/forums/showthread.php?581961-Name-Change-Requests

New link https://twcenter.net/threads/name-change-requests.581961/

This does work on non-friendly URLs, but I do not have many of those.

           return 301 /threads/$arg_t/;
        }

        location = /member.php {
           return 301 /members/$arg_u/;
        }

I think what is throwing me off is the swap between text and id. In vBulletin its id-then-the-text

In XenForo its the-text.id


Solution

  • Of course the $arg_u or $arg_t variables are empty with the request example you've provided. These variables hold the value of the corresponding query argument — for example:

    Instead, you need to work with the $args variable, which contains the full query string. Nginx’s built-in string manipulation capabilities are very limited, but the following approach should work for you:

    map $args $xf_id {
        ~^(\d+)-(.+)$  $2.$1;
    }
    server {
        ...
        location = /forums/member.php {
            return 301 /members/$xf_id/;
        }
        location = /forums/showthread.php {
            return 301 /threads/$xf_id/;
        }
        ...
    }
    

    Nginx does not provide built-in case conversion functions. However, based on a quick test with your URL sample, this setup should work, though it will result in an additional 301 redirect from:

    https://twcenter.net/members/Gaius-Baltar.10263/
    

    to:

    https://twcenter.net/members/gaius-baltar.10263/
    

    Note that the map directive must be declared in the http context, at the same level as the server directive, not inside a server block.