Breadcrumbs?


#1

Before I start down this road, has anyone done a breadcrumbs
implementation they’d be happy to share?

Thanks
Chris T


#2

I’ve only done them by hand. I can’t seem to wrap my head around an
automated process.


#3

On 3/17/06, ChrisT removed_email_address@domain.invalid wrote:

Before I start down this road, has anyone done a breadcrumbs
implementation they’d be happy to share?

The way I have my site set up, each page is an instance of a model
that acts_as_tree, has a “full_path” attribute, and a “title”
attribute (using a mixin). This lets me use a simple helper to build
the breadcrumbs. It looks something like this:

def breadcrumbs(page, separator = “»”)
pages = [page.title] # current page
while page.has_parent?
page = page.parent
pages << link_to(page.title, “/#{page.full_path}”)
end
pages.reverse.join(" #{separator} ")
end

Not sure if that helps for your setup but figured I’d share anyway…

If anyone’s done something more generic I’d also like to see it.

Thanks,
Justin


#4

each page is an instance of a model

What does this mean? The html that is output is and instance of a
model? You have a db table that has a record for each view?

Thanks,
Peter


#5

On 3/17/06, Peter M. removed_email_address@domain.invalid wrote:

each page is an instance of a model

What does this mean? The html that is output is and instance of a
model? You have a db table that has a record for each view?

Each page represents a row in a db table. So if I visit /foo/bar, I
find the row with a path of “foo” who’s parent is a row with path
“bar”

Make sense?

Justin


#6

Thanks
Looks good. My model is a (self-ref) HABTM so will need a bit of
tweaking, but that’s a good start.
Cheers
Chris T


#7

Justin B. wrote:

On 3/17/06, ChrisT removed_email_address@domain.invalid wrote:

Before I start down this road, has anyone done a breadcrumbs
implementation they’d be happy to share?

The way I have my site set up, each page is an instance of a model
that acts_as_tree, has a “full_path” attribute, and a “title”
attribute (using a mixin). This lets me use a simple helper to build
the breadcrumbs. It looks something like this:

def breadcrumbs(page, separator = “»”)
pages = [page.title] # current page
while page.has_parent?
page = page.parent
pages << link_to(page.title, “/#{page.full_path}”)
end
pages.reverse.join(" #{separator} ")
end

Not sure if that helps for your setup but figured I’d share anyway…

If anyone’s done something more generic I’d also like to see it.

Thanks,
Justin

Justin,

Do you generate your page model instances statically when you start the
app. or do you build the tree dynamically as you navigate?

Wes


#8

ChrisT,
I’ve been hard coding breadcrumbs based on the current controller/action
to some success. This works fine when there’s only one trail through a
set of pages, but when different trails converge it can get complicated.

For example, suppose itâ??s possible to arrive at the Edit action through
two paths:
Search -> View -> Edit
Creation -> View -> Edit

Since the breadcrumbs are hard coded, itâ??s difficult to figure out what
to show the user while in Edit, without keeping track of their history
somehow, which gets messy.

I ended up using alias_method() to sort of clone some actions, so I
could give each version itâ??s own breadcrumbs. In this case, I used
something like this:

alias_method :original_edit, :edit
def search_edit
original_edit
end

Now when the user is in the Search leg of their trip, all references to
Edit are actually pointing to Search_edit, which is identical in every
way except the name. And old Edit works, too. Just make sure you put
Edit above the alias_method() call, or else things can go haywire. This
way I can show the appropriate search breadcrumbs while in Search_edit.

I do keep track of form data in sessions (session [:whatever] =
params[:whatever]), which then can be unpacked into fields when the user
clicks back in the breadcrumb trail to a previous page with a form.

I donâ??t know if this is the best way to do breadcrumbs, but it works
without too much extra code. Whipping alias_method() around like this
might not be best practice either, I donâ??t know. Anyone have any
thoughts on it?

ChrisT wrote:

Before I start down this road, has anyone done a breadcrumbs
implementation they’d be happy to share?

Thanks
Chris T


#9

Curtis S. wrote:

On 6/28/06, Doug removed_email_address@domain.invalid wrote:

I’ve been hard coding breadcrumbs based on the current controller/action
to some success. This works fine when there’s only one trail through a
set of pages, but when different trails converge it can get complicated.

I actually had to do this globally for an app in Java. If I had to
design it for RoR, I think I would do a similar thing. Basically I
created a table and structure for the breadcrumbs. There are a few
classes (models) to manage it. It could be implemented via
before_filters and probably could even be refactored into a plugin.
Regardless, a basic breakdown:

id
user_id
page_name
sort_order
url

There was a class that managed that so you could create an entry
simply, and also get back a sorted collection of the user’s breadcrumb
position. It kinda worked like a “stack” (push / pop). Although a
“pop” would clear everything with a sort order equal or higher to the
clicked link.

In RoR, I would probably replace the url field with separate fields
for controller, action, and maybe params or something. Depends on
your needs to be able to backtrack. And again I would utilize
controller before_filter and after_filter definitions to manage the
breadcrumb trail.

-Curtis

Curtis,

Did you have to persist this data it to a DB? Were you wanting to allow
breadcrumbs to work across sessions? scratching head

Wes


#10

On 6/28/06, Doug removed_email_address@domain.invalid wrote:

I’ve been hard coding breadcrumbs based on the current controller/action
to some success. This works fine when there’s only one trail through a
set of pages, but when different trails converge it can get complicated.

I actually had to do this globally for an app in Java. If I had to
design it for RoR, I think I would do a similar thing. Basically I
created a table and structure for the breadcrumbs. There are a few
classes (models) to manage it. It could be implemented via
before_filters and probably could even be refactored into a plugin.
Regardless, a basic breakdown:

id
user_id
page_name
sort_order
url

There was a class that managed that so you could create an entry
simply, and also get back a sorted collection of the user’s breadcrumb
position. It kinda worked like a “stack” (push / pop). Although a
“pop” would clear everything with a sort order equal or higher to the
clicked link.

In RoR, I would probably replace the url field with separate fields
for controller, action, and maybe params or something. Depends on
your needs to be able to backtrack. And again I would utilize
controller before_filter and after_filter definitions to manage the
breadcrumb trail.

-Curtis


#11

On 6/28/06, Wes G. removed_email_address@domain.invalid wrote:

Did you have to persist this data it to a DB? Were you wanting to allow
breadcrumbs to work across sessions? scratching head

Well, see I’m strange. In every case that I’ve developed a
“session-only” mechanism, something went wrong (either I had to
persist it, or someone did something to make it too large to be
practical at a session level). So I’ve gotten to the point that
almost everything goes into the DB. If you delete it when it’s not
neccessary, it doesn’t cause an issue. And if you index properly,
it’s plenty quick.

Short answer no. Long answer, it was easier and cleaner this way…
I don’t mind a few milliseconds on a page load (sessions are coming
from somewhere too…). I also like to “see” what is happening with
my data, and semi-persistent storage is the best way I’ve found to do
that on a consistent, debuggable basis.

You could just as easily create it as a hash of objects that don’t
interact with a DB and just store it in the session. I don’t like
storing objects in sessions for many reasons. The biggest is
“updating” a class and having serialization break on you when you
upload the new version and all currently-sessioned users throwing
exceptions like the plague… Not a good start to a weekend. :wink:

-Curtis