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/.