1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Default route prefix for controller actions

Discussion in 'XenForo Development Discussions' started by Bharimium, Feb 13, 2011.

  1. Bharimium

    Bharimium Member

    Just a quick question about the route prefixes system that has been implemented, which look really nice:

    It looks like the mapping is done in only one direction, you can map a route prefix to a controller and it's action.
    But what if I have a controller and an action and I want to build a link for it?
    There doesn't seem to be such a thing as a "default route prefix".
    If you use the buildPublicLink method, it will try to find a mapped controller, if it doesn't find it, it just goes ahead and uses the "basic" build method

    An example: when someone changes the "members" route prefix to "users", they will have to change all the references in the templates and the code to that prefix (eg. tabs.members.href) in "navigation" template or (XenForo_Dependencies_Public->_getNavigationContainerParams()).

    This would not be needed if each controller had a "default route prefix", which in this case could be changed to "users" while "members" would still exist and work (maybe just redirect it to "users")

    Is that correct or am I missing something?

    Also: in what situations would someone want to have more than 1 route prefix pointing to the same controller?
  2. Shadab

    Shadab Well-Known Member

    A route prefix is not supposed to be changed, IMO. So as an addon developer, you shouldn't fiddle with core route prefixes; and as an end-user, not change the route prefix used by an addon. It's usually not worth the effort to shift any route prefix (unless of course if it's the index route. :p)

    Assigning a default route for a controller wouldn't solve the problem because you can have urls from multiple route prefixes resolving to different actions of different controllers. Like a many-to-many mapping. So you can't really assign a default prefix to a "controller".

    Backward compatibility, I think. Suppose xenforo changes the route prefix from "members" to "users" completely. This would break all the older urls pointing to members/. To maintain BC, xenforo would leave the "members" route prefix intact, and leave it to the canonicalization process to automatically redirect any traffic from members/* to users/*.

    Can't think of any other use-case.
  3. ragtek

    ragtek Guest

    That's also a "scenario" which i'm planing when xenforo brings a global feed.

    Then my add-on will be unnecessary, BUT because of the old url(which many users will still use because it's in there bookmark) , i have to route my old route to the new controller.
  4. Bharimium

    Bharimium Member

    I have just started using XenForo a few days ago, so forgive me if I am completely off base.

    I think I was looking at this the wrong way, what should be done is assigning a default route prefix to every Route Prefix Handler Class.
    What I was thinking about is that there might be some cases where someone would want to change the urls (maybe translate them all)
    There would also need to be a solution for the action names like "create-thread"

    add a public route prefix "users" which points to XenForo_Route_Prefix_Members
    you can now go to the members page via /members or /users (looks like XenForo forgot to put a call to canonicalizeRequestUrl in XenForo_ControllerPublic_Member->actionIndex)
    The method XenForo_Link->_buildLink will have to be updated to see if the given prefix "members" is the default one, if not: change it to the default one: "users"

    add "is_default" field to the table xf_route_prefix:
    SELECT rp.original_prefix FROM xf_route_prefix rp WHERE rp.route_type = ? AND rp.route_class = (SELECT rp2.route_class FROM xf_route_prefix rp2 WHERE rp2.route_type = ? AND rp2.original_prefix = ?) AND rp.is_default;

    Something similar should be done for actions, but then you would also need to update the method XenForo_FrontController->route to change the action name to a valid one (needs extra mapping table in database)
  5. Shadab

    Shadab Well-Known Member

    A route prefix is assigned exactly one handler class. This handler decides how to resolve "sub" routes to a Controller/Action. Any setting for a default route at this level won't make any difference because a controller or an action doesn't usually know which route class was responsible for "passing" the control to it.

    An extra layer of abstraction, which simply hides the route prefix completely from the Controller and View layer would achieve this. Allowing for much easier manipulation of URLs (by addon developers and end-users alike), including translation of prefixes to other languages.

    I'd be glad to see such a feature in XenForo, myself. But is the added complexity really worth it?
  6. Bharimium

    Bharimium Member

    Suppose someone already has a directory called "/forums", but wants to install XenForo in the root.
    Cannot be done like it is now.
    But if you follow these steps, you will understand what I mean with "default route prefix":

    On your test server:
    1) make a folder in the root called "forums", if you go to "/forums" now, it will show the index of the forums folder (we will try to solve this problem by renaming the "forums" prefix)
    2) Go to admin panel -> development and add the route prefix "board", pointing it to "XenForo_Route_Prefix_Forums"
    3) Open the file "/library/XenForo/Link.php"
    4) Add this at the beginning of the protected method "_buildLink":
            $arrTemp explode("/"$type);
            if (
    strcmp($arrTemp[0], "forums")==0) {
    $arrTemp[0] = "board";
    $type implode("/"$arrTemp);
    4)Add this at the beginning of the methods "buildBasicLink", "buildBasicLinkWithIntegerParam" and "buildBasicLinkWithStringParam":
    if ($prefix === "forums"$prefix "board";
    5) Now go to "/" and check out all the links, they will have been changed from "/forums" to "/board"

    Now suppose you would have a field in the table "xf_route_prefix" which is called "is_default" and we will have set that to be true for the "board" prefix, and false for the "forums" prefix.
    Then we could do this in those 4 methods, instead of the hard coded examples which I have given above:
    1) lookup the given prefix, in this case "forums"
    2) Find out for that particular "route class" (in this case "XenForo_Route_Prefix_Forums"), which prefix is the "default one"
    3) Now build your links using that prefix which is set to be default, in this case "board"

Share This Page