Emmek on Rails
2009-May-31 19:23 UTC
How to get a nice url hierarchy with slugs and acts_as_tree?
I have a model Page in my application that acts_as_tree. I want this model to keep whole structure of website. I have some root nodes: home, contact, articles, etc. and the possibility of adding children to them. I want to access these pages using slugs (Page model and new/edit forms have such attribute/field). In show action of pages controller: if params[:slug] @page = Page.find_by_slug(params[:slug]) raise ActiveRecord::RecordNotFound, "Page not found" if @page.nil? else @page = Page.find(params[:id]) end And routing: map.connect '':slug'', :controller => ''pages'', :action => ''show'' Everything works well at the first level but how to access children pages using hierarchy of the tree and slugs? Example structure: Home (pages/1) Articles(pages/2) ----Article1 (pages/5) ----Article2 (pages/6) Contact(pages/3) About (pages/4) I need this kind of access especially in ''Articles'' node. I''d like to access several article using mydomain.com/articles_slug/article1_slug. What is the nice way to do it? Could you post some helpful links or write solution? Any help appreciated. -- Posted via http://www.ruby-forum.com/.
Julien ramel
2009-Oct-01 16:48 UTC
Re: How to get a nice url hierarchy with slugs and acts_as_tree?
Hi Emmek, I never found anything really convincing to handle that, but facing the same problem I found some workaround. So first to get a slug, I use the plugin "ActsAsUrlParam" http://github.com/caring/acts_as_url_param I use it on a page "model" that uses a custom acts_as_tree (with dotted ids, pretty convenient to boost performances) http://github.com/xavier/acts-as-tree-with-dotted-ids Then I created special routes (yeah, to use with caution, I wanted to avoid the "/pages/" prefix ) <code> map.resources :pages map.page_first_level ''/:slug.:format'', :controller=>:pages,:action=>:show map.page_second_level ''/:parent_slug/:slug.:format'', :controller=>:pages,:action=>:show map.page_third_level ''/:ancestor_slug/:parent_slug/:slug.:format'', :controller=>:pages,:action=>:show </code> finally in my page helper <code> module PagesHelper def smart_page_path(page,format=nil) case page.depth when 0 page_first_level_path(page.slug,:format=>format) when 1 page_second_level_path(page.parent.slug,page.slug,:format=>format) when 2 page_third_level_path(page.parent.parent.slug, page.parent.slug,page.slug,:format=>format) else page_path(page) end end end </code> it uses the page depth to generate my nice formatted URL as result, using smart_page_path(@page) -Home -> /home.html -About -> /about.html ---History -> /about/history.html ---Team -> /about/team.html -Projects -> /projects.html ---Global -> /projects/global.html -----Ecology -> /projects/global/ecology.html -----Human rights -> /projects/global/human-rights.html ---Local -> /projects/local.html -Contact -> /contact.html BUT!! - the extra params are just meant for SEO, you can use any routes, only the last slug will be used (/my-dummy-param/about.html) - maybe it''s not that good to use routes that starts from the root.... I always use an "admin" namespace fro my admin sections, so I never have much at the root anyway. If someone has a better idea I''ll be delighted to hear it. -- Posted via http://www.ruby-forum.com/.
Marnen Laibow-Koser
2009-Oct-01 16:59 UTC
Re: How to get a nice url hierarchy with slugs and acts_as_t
Emmek on Rails wrote:> I have a model Page in my application that acts_as_tree. I want this > model to keep whole structure of website.Then I would strongly suggest awesome_nested_set instead of acts_as_tree. It makes it possible to use the DB *much* more efficiently.> I have some root nodes: home, > contact, articles, etc. and the possibility of adding children to them. > > I want to access these pages using slugs (Page model and new/edit forms > have such attribute/field). In show action of pages controller: > > if params[:slug] > @page = Page.find_by_slug(params[:slug]) > raise ActiveRecord::RecordNotFound, "Page not found" if @page.nil? > else > @page = Page.find(params[:id]) > end > > And routing: > > map.connect '':slug'', :controller => ''pages'', :action => ''show'' > > Everything works well at the first level but how to access children > pages using hierarchy of the tree and slugs?I''m not sure. You might need to use a *glob route for the page path, then do your own parsing. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/.
Marnen Laibow-Koser
2009-Oct-01 17:02 UTC
Re: How to get a nice url hierarchy with slugs and acts_as_t
Marnen Laibow-Koser wrote:> Emmek on Rails wrote: >> I have a model Page in my application that acts_as_tree. I want this >> model to keep whole structure of website. > > Then I would strongly suggest awesome_nested_set instead of > acts_as_tree. It makes it possible to use the DB *much* more > efficiently.Actually, on second thought, this might be a good use case for a materialized path in the DB. Then you could just do find_by_path to retrieve any page at any depth. Best, -- Marnen Laibow-Koser http://www.marnen.org marnen-sbuyVjPbboAdnm+yROfE0A@public.gmane.org -- Posted via http://www.ruby-forum.com/.