Good question, the answer is yes and also no. Yes, you can organize them in folders, but not arbitrarily. In short they must match your route hierarchy. I think you can probably do what you want with a few adjustments but it depends on how you want things to be rendered.
Let’s look at the router:
Router.map(function () {
this.route('legal/terms-of-service', { path: '/legal/terms-of-service' });
... ^ this is route name ^ this is route path
});
the route javascript file, and route template hbs file MUST match the “route name”. Route names should basically just be kebab case strings with no slashes. There are two ways to build your router here:
- flat router with customized paths, UI is not nested, but the file system cannot be either
- nested routes, UI is nested, file system is nested into directories too
I assume #2 is probably what you want but let’s look at them both.
1. Flat router
The router might look something like this:
Router.map(function () {
this.route('legal-terms-of-service', { path: '/legal/terms-of-service' });
this.route('legal-privacy-policy', { path: '/legal/privacy-policy' });
...
});
Which results in the following (named) routes:
legal-terms-of-service
legal-privacy-policy
The route/template files would be located as follows:
/app/routes/legal-terms-of-service.js
/app/routes/legal-privacy-policy.js
/app/templates/legal-terms-of-service.hbs
/app/templates/legal-privacy-policy.hbs
To create a link to those routes it would look like:
<LinkTo @route="legal-terms-of-service" ... />
<LinkTo @route="legal-privacy-policy" ... />
which would generate links with the following hrefs:
/legal/terms-of-service
/legal/privacy-policy
2. Nested routes
Router.map(function () {
this.route('legal', function() {
this.route('terms-of-service', { path: '/terms-of-service' });
this.route('privacy-policy', { path: '/privacy-policy' });
...
});
...
});
The routes/templates should look like:
/app/routes/legal.js // implicit
/app/routes/legal/index.js // implicit
/app/routes/legal/terms-of-service.js
/app/routes/legal/privacy-policy.js
/app/templates/legal.hbs //implicit
/app/templates/legal/index.hbs // implicit
/app/templates/legal/terms-of-service.hbs
/app/templates/legal/privacy-policy.hbs
Which results in the following (named) routes, note the “.” separator at the parent/child boundary:
legal.index
legal.terms-of-service
legal.privacy-policy
To create a link to those routes it would look like:
<LinkTo @route="legal.terms-of-service" ... />
<LinkTo @route="legal.privacy-policy" ... />
which would generate links with the following hrefs:
/legal/terms-of-service
/legal/privacy-policy
I’m guessing this second version is what you’re looking for
Notes
Note that in the second (nested) option you end up with more routes. Ember implicitly creates an index route anytime there are child routes. This means that if someone visited /legal
it wouldn’t throw an error, which is good. But by default the index route isn’t going to show anything. So there are two common ways to handle that:
- Just redirect to the default “legal” child route in the legal/index.js route file
- Set the path for one of the child routes to be
'/'
which makes it the new index route even if it’s not named index
Anothing thing to note is that with child routes the UI is nested. So in the above case the legal.hbs
template is implicitly created for you with just an outlet. But if you wanted something to render across all your legal routes (like a special navbar or something) you could put it in that legal.hbs
template above or below the outlet and it will render the child templates in the outlet. This is the same as the ember application route, just scoped to a smaller subset of routes.