2015-09-08 10 views
5

ここは私のメッセージエンティティです。私のアプリでユーザー間のメッセージを定義するクラスです。twigにネストされた配列を表示

class Message 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @var string 
    * @Assert\NotBlank(message="private_message.title.blank") 
    * @ORM\Column(name="title", type="string", length=50) 
    */ 
    protected $title; 

    /** 
    * @Assert\NotBlank(message="private_message.receiver.blank") 
    * @ORM\ManyToOne(targetEntity="MedAppBundle\Entity\User") 
    * @ORM\JoinColumn(referencedColumnName="id") 
    */ 
    protected $receiver; 
    /** 
    * @ORM\ManyToOne(targetEntity="MedAppBundle\Entity\User") 
    * @ORM\JoinColumn(referencedColumnName="id") 
    */ 
    protected $sender; 

    /** 
    * @var string 
    * @Assert\NotBlank(message="private_message.content.blank") 
    * @ORM\Column(name="content", type="string") 
    */ 
    protected $content; 

    /** 
    * @var \DateTime 
    * 
    * @ORM\Column(name="sentAt", type="datetime") 
    */ 
    protected $sentAt; 


    /** 
    * @var boolean 
    * 
    * @ORM\Column(name="isSpam", type="boolean") 
    */ 
    protected $isSpam = false; 


    /** 
    * @var \DateTime 
    * 
    * @ORM\Column(name="seenAt", type="datetime",nullable=true) 
    */ 
    protected $seenAt = null; 

    /** 
    * @ORM\ManyToOne(targetEntity="PrivateMessageBundle\Entity\Message") 
    * @ORM\JoinColumn(referencedColumnName="id",nullable=true) 
    */ 
    protected $replyof; 

    /** 
    * @ORM\OneToMany(targetEntity="PrivateMessageBundle\Entity\Message", mappedBy="replyof") 
    **/ 
    private $replies; 

    public function __construct() { 
     $this->replies = new ArrayCollection(); 
    } 

何に注意することが重要なのは、メッセージの親が何であるかを伝えますメッセージreplyof変数、です。 NULLの場合、メッセージは返信ではなく、親メッセージ(ルート)です。

そして、messages変数は、メッセージへの返信であるメッセージの配列です。これらの返信には返信がある可能性があります。この配列は、リーフノードには何も返されないため、NULLでもかまいません。

他のすべての変数には、2人のユーザー間の実際のメッセージを定義するフィールドが含まれています。

私は何をしようとしていることは小枝私のすべてのメッセージの表示のようなので、樹枝状の形式になります。

message1 - root message, reply of none, but has replies 
    reply1 - first reply of message 1 
     reply1 first reply of reply 1 of message 1, leaf with no further replies 
    reply2 - second reply of message 1, leaf with no further replies 

message2 - root message, no replies and a reply of none 

問題は小枝だけforeachループをサポートし、私はどのようにわからないということです2より大きい深度のときにこの形式を表示します。

{% for reply in message.replies %} 
    <li> sent by: {{ reply.sender }} </li> 
    <li> title: {{ reply.title }} </li> 
    <li> content: {{ reply.content }} </li> 
    <li> date: {{ reply.sentAt|date('d-m-Y H:i:s') }} </li> 
    <hr> 
{% endfor %} 

これはメッセージのすべての返信を表示しますが、ネストされたメッセージを完全に表示するにはどうすればよいですか?

+3

[Twig - ツリーのレンダリング方法](http://stackoverflow.com/questions/8326482/twig-how-to-render-a-tree)を見たことがありますか? – HPierce

答えて

2

私はあなたがそれをテストすることはできませんでしたプライ:

{% for reply in message.replies %} 
    {% if loop.first %}<ul>{% endif %} 
    <li> sent by: {{ reply.sender }} </li> 
    <li> title: {{ reply.title }} </li> 
    <li> content: {{ reply.content }} </li> 
    <li> date: {{ reply.sentAt|date('d-m-Y H:i:s') }} </li> 
    {% for reply in reply.replies %} 
     {% if loop.first %}<li><ul>{% endif %} 
     <li> sent by: {{ reply.sender }} </li> 
     <li> title: {{ reply.title }} </li> 
     <li> content: {{ reply.content }} </li> 
     <li> date: {{ reply.sentAt|date('d-m-Y H:i:s') }} </li> 
     {% if loop.last %}</ul></li>{% endif %} 
    {% endfor %} 
    {% if loop.last %}</ul>{% endif %} 
{% endfor %} 

これには2レベルの返信しか表示されません。あなたは再帰的に回答を表示する必要があり、再利用可能な機能を定義するために小枝macroを使用することができます。

{# define the macro #} 
{% macro displayReply(reply) %} 
    <li> sent by: {{ reply.sender }} </li> 
    <li> title: {{ reply.title }} </li> 
    <li> content: {{ reply.content }} </li> 
    <li> date: {{ reply.sentAt|date('d-m-Y H:i:s') }} </li> 
    {% for reply in reply.replies %} 
     {% if loop.first %}<li><ul>{% endif %} 
     {{ displayReply(reply) }} 
     {% if loop.last %}</ul></li>{% endif %} 
    {% endfor %} 
{% endmacro %} 

{# use the macro #} 
{% for reply in message.replies %} 
    {% if loop.first %}<ul>{% endif %} 
    {{ displayReply(reply) }} 
    {% if loop.last %}</ul>{% endif %} 
{% endfor %} 

クエリによっては、それは間違った順序で回答を表示することがあり、あなたがあなたのクエリで降順に回答をソートする必要があるかもしれません。

1

あなたは次のように再帰的なアプローチを行うことができます。メイン小枝に

を、あなたがメインのメッセージを印刷し、次のように部分的に再帰的に繰り返す:

## main twig 
Root message: 
    <ul> 
    <li> sent by: {{ message.sender }} </li> 
    <li> title: {{ message.title }} </li> 
    <li> content: {{ message.content }} </li> 
    <li> date: {{ message.sentAt|date('d-m-Y H:i:s') }} </li> 
    {{ include('AcmeDemoBundle:Message:_elem.html.twig', {'replies': message.replies) }} 
    </ul> 

## AcmeDemoBundle:Message:_elem.html.twig 
<ul> 
{% for reply in replies %} 
    <li> sent by: {{ reply.sender }} </li> 
    <li> title: {{ reply.title }} </li> 
    <li> content: {{ reply.content }} </li> 
    <li> date: {{ reply.sentAt|date('d-m-Y H:i:s') }} </li> 
    {{ include('AcmeDemoBundle:Message:_elem.html.twig', {'replies': reply.replies) }} 
{% endfor %} 
</ul> 

このヘルプを参考にしてください

関連する問題