So the problem here is fundamentally that Scala is inferring loc.currentValue to be a Box[Any], so param ends up being a Box[Any].
Now, my experience with SiteMap isn't *super* extensive, but I think this is because S.location is not meant to get you the location the way you're using it. Typically, when you have a param that you build using Menu.param[T], you assign the Menu.param result to, say, a variable called menu. Then you can use menu.toLoc.currentValue to extract the actual value of the param. At this point, you've preserved the type safety, because the result of Menu.param[T] is ~ a ParamMenuable[T]. The toLoc method of a ParamMenuable[T] yields a Loc[T], and its currentValue method in turn yields a Box[T]. Thus, you maintain the typing information throughout that chain.
However, if you call S.location, there's no way to know which particular menu item you're referring to, so there's no way to know that we're talking about a Menu.param that gives you a (String,String).
Thus, you have two options here. One is to get the value out of the Menu.param[T] call that you used. The other is to try casting the content of the S.location value yourself. You can do that with Box.asA:
val param = for {
loc <- S.location ?~ "no value"
value <- loc.currentValue ?~ "no value"
param <- Box.asA[(String,String)](value) ?~ "value was the wrong type"
} yield param
Box.asA[T](value) checks value. If value is a T, then it returns a Full box with the properly cast value in it. If value is some other type, it returns an Empty Box (which in this case will be converted to a Failure).
The result above should be that param is a Box[(String,String)].
As to the second part, you want to unpack the tuple like so:
var threadBox : Box[code.model.ForumThread] = for {
(identServer, identClient) <- param ?~ "no value"//2
p <- code.model.ForumThread.getByIdent(identServer, identClient) ?~ "user no found" //3
} yield p
This should yield far more readable code (of course once the identServer and identClient variables are named properly). But, this will only work properly if the type of param is a Box[(String,String)].
Hope that helps, feel free to ask for any clarification you may need!
Thanks,
Antonio
PS: There may be some type erasure issues with Box.asA[(String,String)], since that's really just Box.asA[Tuple2[String,String]]; I'm not sure about that.