Accommodating mod_rewrite urls


#1

I have a client running a traditional server-side application who is OBSESSED with their SEO-friendly urls. They look like this:

http://www.site.com/shirts/t-shirts/childrens // category url (i.e. nothing in the url indicates it’s a category)

http://www.site.com/shirts/t-shirts/childrens/pink-shirt.html // product url (only indication it’s a product is that the path matches a category and the url ends in .html)

I’d like to eventually convert them to Ember but I know URLs are going to be an issue with them. Even though rewrites and redirects could still be handled by the server, they are not gonna like seeing this:

/category/233

in the location bar. I’m wondering if I could set up the ember routing to mimic their current url structure, and if so, if that’s a reasonable approach.

If it is reasonable, probably the easiest thing would be to use the path elements (like ‘t-shirts’) as the id for the model (rather than a number). Then, (and I don’t know if this is possible) but I’m thinking in the router.js file I could load a JSON object like:

{
	"categories": {
		"shirts": {
			"t-shirts": {
				"childrens": "",
				"adults": ""
			},
			"sweatshirts": {
				"childrens": "",
				"adults": ""
			}
		},
		"hats": {
			"baseball": "",
			"cowboy": ""
		}
	}
}

Then maybe split the incoming route by ‘/’ and loop through the elements and then progressively test each iteration against that object.

If the loop completes and there’s a match, then it’s a valid category - use the last element as the ID.

If the loop completes and everything matches except the last one, and the last one has .html at the end, it’s a product, use last element as the product ID (sans .html) and use the matched path to generate the breadcrumb trail.

That’s shooting from the hip. I just wanted to explore the issue here and see if this would be a reasonable approach and if so, if anyone has done something like this. Thanks!


#2

You can use slugs defined on the model in your routes. We do this for example here http://www.tvg.nl/contact/contactgegevens

So it is a reasonable approach.


#3

OK - thanks. Good to know ember accommodates this. Couple things I’m running into:

There’s not much in my client’s urls that clearly denotes it’s a product or a category route.

This looks like it would be easy to implement as a slug:

http://www.site.com/category/shirts

with this in router.js:

this.route('category', { path: '/category/:category_slug'});

but not this:

http://www.site.com/shirts/t-shirts/childrens

unless I explicitly specify all the top-level categories in the router like this:

this.route('category', { path: '/shirts/:category_slug'});
this.route('category', { path: '/hats/:category_slug'});

That’s do-able but I’d love to avoid specifying things like that explicitly.

Secondly, the router seems only to be able to handle the top-level paths. I’m trying this:

http://www.site.com/category/shirts/t-shirts/childrens with this in the router: this.route('category', { path: '/category/:category_slug'});

But it’s not resolving because it’s looking for the subroutes

I know I can use a wildcard like this:

this.route('category', { path: '/*path'});

and then it looks like in the category route’s model hook I can then parse params.path and make the breadcrumb and ID for the category

BUT that still leaves the issue of how to handle products. Seems like this path-parsing logic should be handled in the router.js file rather than the route. Trying now to figure out how to do that.

Can you access the raw path and do conditional routing in router.js? I guess a different way to do it would be to have the router transition to an intermediary route (perhaps index?) that handles the parsing of the url and determines whether it’s a product or category, THEN do the dinal transition