1
votes

If I have a typical entry in my routes file for importing routes from a module

*       /admin                  module:crud

is there a way for me to determine that the base path for the crud module is /admin, other than just parsing the main routes file myself? It doesn't appear that the Router class keeps this information.

The ultimate goal is to create a menu for each module. If I have a user management module imported at /useradmin, I want to generate a menu containing /useradmin/users and /useradmin/groups but not deeper descendants such as /useradmin/users/new. If /useradmin is routed to something, I'll use that as the link for the menu's label, otherwise I'll just show a plain text label.

While I might be able to fake it without knowing, it seems like knowing the actual base url for the module would be the best way to ensure I can handle various special cases such as modules imported at /modules/useradmin or modules that grandchild paths but no child paths (/useradmin/users/new but no /useradmin/users).

2

2 Answers

2
votes

the question is: why do you need to parse the file or know that '/admin' is the base? Play allows you to use reverse routing to get the path.

From the link above:

For example, with this route definition:

GET    /clients/{id}      Clients.show

From your code, you can generate the URL able to invoke Clients.show:

map.put("id", 1541);
String url = Router.reverse("Clients.show", map).url;  // GET /clients/1541

That should be enough.

1
votes

Just now, I don't see anything else than parsing the route yourself. Look at the play.mvc.Router class IMO and following function :

static void parse(VirtualFile routeFile, String prefix) {
    String fileAbsolutePath = routeFile.getRealFile().getAbsolutePath();
    int lineNumber = 0;
    String content = routeFile.contentAsString();
    if (content.indexOf("${") > -1 || content.indexOf("#{") > -1 || content.indexOf("%{") > -1) {
        // Mutable map needs to be passed in.
        content = TemplateLoader.load(routeFile).render(new HashMap<String, Object>(16));
    }
    for (String line : content.split("\n")) {
        lineNumber++;
        line = line.trim().replaceAll("\\s+", " ");
        if (line.length() == 0 || line.startsWith("#")) {
            continue;
        }
        Matcher matcher = routePattern.matcher(line);
        if (matcher.matches()) {
            String action = matcher.group("action");
            // module:
            if (action.startsWith("module:")) {
                String moduleName = action.substring("module:".length());
                String newPrefix = prefix + matcher.group("path");
                ...

It extracts the prefix which is the part you look for.