Recursive blocks in Scala Play Framework templates
Asked Answered
N

3

6

I'm writing a template for a blog post, which has threaded comments. A natural way of writing a template for threaded comments it use a recursive way for constructing the Html. Something like this:

@showComment(comment: models.Comment) = {
    <div class="comment">
        <div class="comment-metadata">
            <span class="comment-author">by @comment.author,</span>
            <span class="comment-date">
                @comment.postedAt.format("dd MMM yy")
            </span>
        </div>
        <div class="comment-content">
            <div class="about">Detail: </div>
            @Html(comment.content.replace("\n", "<br>"))
        </div>
        <a href="@action(controllers.Application.replyComment(comment.id()))">Reply</a>
        @comments filter { c => c.parent_id == comment.id } map { 
            c => @showComment(c)
        }
    </div>
}

The problem is that using a recursive block yields the error:

Error raised is : recursive method showComment needs result type

If I try to put a return type in the showComment it raises this errror:

Error raised is : not found: value showComment

Any workaround?

Northampton answered 9/10, 2011 at 21:32 Comment(0)
P
4

This works for me:

Enclose code in @{}

@{

    //use regular scala here:
    def showComment(comment: models.Comment):Node = {
    ....
    }
    //the above just declared a recursive method, now call it:

   showComment(...)

}
  • define recursive method
  • call the method at the end of the block
  • profit !
Ppm answered 8/12, 2012 at 15:6 Comment(0)
R
2

I was able to get past this by moving the recursive template into its own file.

Ramon answered 3/2, 2015 at 3:47 Comment(0)
D
0

In Scala, recursive method require a return type: See Why does Scala require a return type for recursive functions?

I don't know much (more like nothing) about the Play Framework but try:

@showComment(comment: models.Comment):Node = {
<div class="comment">
    <div class="comment-metadata">
        <span class="comment-author">by @comment.author,</span>
        <span class="comment-date">
            @comment.postedAt.format("dd MMM yy")
        </span>
    </div>
    <div class="comment-content">
        <div class="about">Detail: </div>
        @Html(comment.content.replace("\n", "<br>"))
    </div>
    <a href="@action(controllers.Application.replyComment(comment.id()))">Reply</a>
    @comments filter { c => c.parent_id == comment.id } map { 
        c => @showComment(c)
    }
</div>
}
Dagon answered 10/10, 2011 at 0:13 Comment(3)
It seems play templates do not allow to set return types. And as a consequence no recursion at all.Northampton
@FelipeHummel Seems limiting. What if you return a play.template.Html instead of a Node?Dagon
same error: "Error raised is : not found: value showComment" =\Northampton

© 2022 - 2024 — McMap. All rights reserved.