-
Notifications
You must be signed in to change notification settings - Fork 299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support strictly hierarchical product views and URLs #101
Comments
Taking a look at option 1, I've run into a small problem: Category is a Page, but Product is not. So Category has a "fully qualified" slug ("store/hardware") served by a mezzanine view, but Product has a relative slug ("product-1") served by a cartridge view. Simply joining these almost works, except it only makes sense to do so in |
See above quick-and-dirty hack, which seems to work for my purposes.. |
Won't your new urlpattern prevent regular Mezzanine pages from being matched? |
Yes, I suppose it would, for any Page created within the Some possible remedies, all a bit icky:
Other ideas...? |
Here's a variation on the second bullet, which on balance doesn't seem very nasty: ac345f4. See the justification there. |
(Bizarre that the commit hash auto-linked & renders within this repo rather than mine. I think this is a github bug, shot it over to support.) |
Firstly I just wanna say that I really do appreciate what you're trying to solve here. I've had the exact same problem in the past with ecommerce sites, and working out what the canonical category is for the sake of a nicer URL, and more importantly for breadcrumb navigation. Interestingly, it's actually a broader problem that comes up in other cases as well, such as news sites where stories can appear in multiple sections of a site. Let's forget about breadcrumbs for a moment and just think about the URL structure. I think with all the options you've come up with (which are all really clever, and it's great they actually work), you've basically shown that no matter which way we wrangle this, we're gonna end up with an ugly overall design whereby we end up with multiple code paths for handling the category and product views. Categories are Mezzanine pages - they can pretty much fall under any urlpattern - this is a great feature I think, it allows people to set up site hierarchies however they choose to. But products aren't pages, and I'd argue rightly so - they don't belong in the navigation structure of the site. So taking Mezzanine pages into account, taking Django urlpatterns into account, and specifically the need for a specific urlpattern that matches products (eg /product/some-slug/), I think the whole idea of trying to include category slugs in the URLs for products really just falls apart. I guess we could somehow have product slugs actually include the slug of their canonical category, but we'd still need the urlpattern prefixed with the unique /product/ part, so we wouldn't end up with perfect URLs anyway. To top all that off - if someone really wants this, and can actually get this working in the context of their own project, then that's great and I'd totally suggest doing it. Perhaps we can take some of the stuff you've put together here and put it into a separate app, cartridge-canonical-categories or some such. I just think that if we try and implement this in Cartridge itself, it's a slippery slope downward towards corrupting the overall flow of how each of the urlpatterns and views work together. We'd lose a great deal of simplicity at the cost of changing the URLs slightly in some cases. I just don't think it's worth it. Now for my mind, I think the urlpatterns are of little relative importance when compared to the breadcrumb issue - I think in the case of each product only belonging to single category, having the breadcrumb nav in the product template reflect this would actually be an extremely useful feature. So I'd actually really like to solve that, and I think we can do it in a pretty clean way, clean at least when compared to all the issues that come up with trying to make this happen for URLs. Not sure what the end result for getting breadcrumbs working might look like - it could be a setting like you described, and that controls in the template whether we use a special template tag that handles rendering the breadcrumbs for a product and its one and only category. |
Thanks for your thoughts! I appreciate the consideration. More inline.
Agreed; I think this is the status quo and not worth changing.
I think I've got my head around the distinction now, thanks.
I think I see now. It specifically breaks down if a Category is rooted outside of the shop, ie, the Category's slug is not a child of / does not begin with Curious, do you think this is common? Though Categories have all the flexibility of Pages and can be scattered anywhere, do many cartridge sites take advantage of this this? I couldn't find any examples in spot checking a few of the sites on the list: for example, Cotton On (by all accounts an impressively customized site!) seems to use This issue aside, the resulting logic should be straightforward: A product's URL is either:
(I would separately propose tacking
It's probably a bad idea; the product's slug would be brittle in the face of changes to its canonical category.
I do like cartridge's philosophy of intentionally minimizing bundled functionality, though I'm not quite sure how to package this separately (it would no doubt involve monkey-patching
Acknowledged. From my perspective -- which is very limited -- perhaps there are at least two broad "styles" of stores that could be supported in cartridge, with slightly different requirements:
In my case, I don't ever envision needing (a) categories outside of
I'm certainly fine for separating the issues! The loss of context in the breadcrumbs (for example, on "Adrenaline") once you drill down into a product is jarring. I can live with opaque URLs, but loss of context while browsing my store is what originally sent me down this route.. FWIW and to my surprise, breadcrumbs "just worked" with my change -- the store and category breadcrumbs are correctly displayed and linked on the (category-slugified) product page. I suspect it may break with sub-categories, but I haven't tried. This also relies on the earlier assumption that categories are children of the main shop/ category. Whew, that was longer than expected, sorry for the verbosity.. [edit: typos] |
FYI: Not adding anything new to the discussion, but here's a consolidated change: 51e5f7d |
Sorry about the delay on this - I'm just giving it a lot of thought. The last commit you linked to is really useful and with everything boiled down into that, I think we're on the right track. We might be able to achieve it even a bit more simply, but still trying to flesh that out in my head :-) |
No worries! I'm on vacation this week, take your time. Glad I at least have you intrigued :) |
FYI (again nothing new, just for illustration) my store is now online with this change: https://kegbot.org/store/ |
Rebased change for anyone still following along: 655154c |
will it be included in cartridge, or I should patch it my self? |
Hi Stephen,
I'd like to support a strict hierarchy of products. Perhaps an illustration of the desired outcome will explain best.
Here's what the store's left nav and URLs would ideally look like:
On each product page, I'd like to render the nav bar and breadcrumbs in terms of each product's one (and only) category, ie:
Today each product has a ManyToMany relationship to zero or more Categories. I see two ways to support this:
Option 1
Modify Product.get_absolute_url() to inspect Product.categories to find the Product's canonical category.
When len(self.categories) == 1, return a different view mapped to the URL
/<category_slug>/<slug>/
instead of/product/<slug>/
.Pro:
Con:
Option 2
Add a new field to Product indicating the "primary" category:
Pro:
get_absolute_url
.Con:
Perhaps you have other ideas. I am leaning towards option 1; it could be gated by a feature flag (default off) out of concern for extra DB load.
One other thought: A view serving
/<category_slug>/<product_slug>/
should be forgiving in the event thatcategory_slug
does not match the product's category.Since
product_slug
unambiguously identifies the product, the view should issue a 301 redirect toproduct.get_absolute_url()
. This keeps hierarchical URLs while allowing categories to be renamed/changed in the future.The text was updated successfully, but these errors were encountered: