在树枝模板中显示表中的分层数据

时间:2013-10-17 17:55:14

标签: php symfony doctrine-orm twig hierarchy

我正在使用Symfony2和Twig:我有一个表,用于处理Doctrine的分层数据。这是一个类别列表,其中包含parent-> children-> sub_children-> sub_sub_children等...许多变体。

我可以像这样在页面上显示它们,但问题是没有“缩进”来显示哪个元素属于父母或孩子或孩子等等。

 <table class="table" id="tableList">
            <thead>
            <tr>
                <th>Category Name</th>
            </tr>
            </thead>
            <tbody>
            {% for productCategory in productCategories %}
                <tr>
                    <td>{{ productCategory.name }}</td>
                </tr>
            {% endfor %}
            </tbody>
        </table>

我希望列表看起来像这样:

 Parent 
      Child
           Child
 Parent
      Child
 Parent
      Child
           Child
                Child

而不是这样:

 Parent
 Child
 Child
 Child
 Parent
 Child
 Parent
 etc.
 etc.

原始实体:

 <?php

 namespace WIC\ProductCategoryBundle\Entity;

 use Doctrine\ORM\Mapping as ORM;
 use Doctrine\Common\Collections\ArrayCollection;
 use Gedmo\Mapping\Annotation as Gedmo;
 use WIC\CommonBundle\DoctrineExtensions\Mapping\Annotation as Common;
 use Symfony\Component\Validator\Constraints as Assert;


 /**
  * ProductCategory
  *
  * @ORM\Table()
  * @ORM\Entity(repositoryClass="Gedmo\Tree\Entity\Repository\NestedTreeRepository")
  * @Gedmo\Tree(type="nested")
  * @Common\Loggable(logEntryClass="WIC\ProductCategoryBundle\Entity\ProductCategoryLog")
  * @Common\Accountable
  * @Gedmo\SoftDeleteable(fieldName="deletedAt")
  */
 class ProductCategory
 {
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 * @ORM\Column(name="name", type="string", length=255, nullable=false)
 * @Common\Versioned
 * @Assert\NotBlank(message="Location Name Cannot Be Left Blank.")
 */
protected $name;

/**
 * @Gedmo\TreeLeft
 * @ORM\Column(name="lft", type="integer")
 */
protected $lft;

/**
 * @Gedmo\TreeLevel
 * @ORM\Column(name="lvl", type="integer")
 */
protected $lvl;

/**
 * @Gedmo\TreeRight
 * @ORM\Column(name="rgt", type="integer")
 */
protected $rgt;

/**
 * @Gedmo\TreeRoot
 * @ORM\Column(name="root", type="integer", nullable=true)
 */
protected $root;

/**
 * @Gedmo\TreeParent
 * @ORM\ManyToOne(targetEntity="ProductCategory", inversedBy="children")
 * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
 */
protected $parent;

/**
 * @ORM\OneToMany(targetEntity="ProductCategory", mappedBy="parent")
 * @ORM\OrderBy({"lft" = "ASC"})
 */
protected $children;

/**
 * @ORM\ManyToMany(targetEntity="WIC\ProductBundle\Entity\Product", mappedBy="productCategories", cascade={"persist"})
 */
protected $products;

/**
 * @ORM\ManyToOne(targetEntity="WIC\UserBundle\Entity\User")
 * @ORM\JoinColumn(name="created_by", referencedColumnName="id")
 * @Common\Blameable(on="create")
 */
private $createdBy;

/**
 * @ORM\ManyToOne(targetEntity="WIC\UserBundle\Entity\User")
 * @ORM\JoinColumn(name="updated_by", referencedColumnName="id")
 * @Common\Blameable(on="update")
 */
private $updatedBy;

/**
 * @ORM\ManyToOne(targetEntity="WIC\AccountBundle\Entity\Account", inversedBy="productCategorys", cascade={"remove","persist"})
 * @ORM\JoinColumn(name="account_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
 * @Common\Versioned
 * @Common\Blameable(on="create")
 */
protected $account;


/**
 * @var datetime $created
 *
 * @Common\Timestampable(on="create")
 * @ORM\Column(type="datetime")
 */
private $created;

/**
 * @var datetime $updated
 *
 * @Common\Timestampable(on="update")
 * @ORM\Column(type="datetime", nullable=true)
 */
protected $updated;

/**
 * @ORM\Column(name="deletedAt", type="datetime", nullable=true)
 */
private $deletedAt;


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


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set name
 *
 * @param string $name
 * @return ProductCategory
 */
public function setName($name)
{
    $this->name = $name;

    return $this;
}

/**
 * Get name
 *
 * @return string 
 */
public function getName()
{
    return $this->name;
}


public function setLvl(ProductCategory $lvl = null)
{
    $this->lvl = $lvl;
}

public function getLvl()
{
    return $this->lvl;
}


public function setParent(ProductCategory $parent = null)
{
    $this->parent = $parent;
}

public function getParent()
{
    return $this->parent;
}

/**
 * Set account
 *
 * @param \WIC\AccountBundle\Entity\Account $account
 * @return User
 */
public function setAccount(\WIC\AccountBundle\Entity\Account $account = null)
{
    $this->account = $account;

    return $this;
}


/**
 * Get account
 *
 * @return \WIC\AccountBundle\Entity\Account
 */
public function getAccount()
{
    return $this->account;
}

/**
 * Add product
 *
 * @param \WIC\ProductBundle\Entity\Product $product
 * @return Product
 */
public function addProduct(\WIC\ProductBundle\Entity\Product $product)
{
    $this->products[] = $product;

    return $this;
}

/**
 * Remove product
 *
 * @param \WIC\ProductBundle\Entity\Product $product
 */
public function removeProduct(\WIC\ProductBundle\Entity\Product $product)
{
    $this->products->removeElement($product);
}

/**
 * Set products
 *
 * @return Product
 */
public function setProducts($products)
{
    $this->products = $products;

    return $this;
}

/**
 * Get products
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getProducts()
{
    return $this->products;
}

/**
 * Set updated
 *
 * @param \DateTime $updated
 * @return User
 */
public function setUpdated($updated)
{
    $this->updated = $updated;

    return $this;
}

/**
 * Get updated
 *
 * @return \DateTime
 */
public function getUpdated()
{
    return $this->updated;
}

/**
 * Set deletedAt
 *
 * @param \DateTime $deletedAt
 * @return User
 */
public function setDeletedAt($deletedAt)
{
    $this->deletedAt = $deletedAt;

    return $this;
}

/**
 * Get deletedAt
 *
 * @return \DateTime
 */
public function getDeletedAt()
{
    return $this->deletedAt;
}

public function getOptionLabel()
{
    return str_repeat(
            html_entity_decode('&nbsp;', ENT_QUOTES, 'UTF-8'),
            ($this->getLvl() + 0 ) * 3
    ) . $this->getName();
}


}

任何人都知道如何做到这一点?

非常感谢!

2 个答案:

答案 0 :(得分:4)

使用无序列表缩进会更容易,因为它们会自动通过浏览器的默认用户代理样式表缩进。这应该这样做:

将此方法添加到ProductCategory实体:

public function getChildren() {
    return $this->children;
}

并在你的树枝模板中

{% for productCategory in productCategories %}
    {{ _self.display_tree(productCategory) }}
{% endfor %}

{% macro display_tree(level) %}
    <ul>
        <li>{{ level.name }}
        {% if level.children|default() %}
            {% for child in level.children %}
                {{ _self.display_tree(child) }}
            {% endfor %}
        {% endif %}
        </li>
    </ul>
{% endmacro %}

答案 1 :(得分:0)

稍微升级到之前的答案。

<ul>
{% for productCategory in productCategories %}
    {{ _self.display_tree(productCategory) }}
{% endfor %}
</ul>

{% macro display_tree(level) %}
    <li>{{ level.name }}
    {% if level.children|default() %}
        <ul>
        {% for child in level.children %}
            {{ _self.display_tree(child) }}
        {% endfor %}
        </ul>
    {% endif %}
    </li>
{% endmacro %}

这会构建更好看的HTML。