2013-11-27 72 views
4

請問是否有語法將「for」標記中的某些元素分開?Twig:「for」標記中的分隔符

比如我有一個用戶列表,我想有一個展示自己的用戶名「 - 」分隔符,所以預期的結果將是:Mickael - Dave - Chris - ...

我發現這個解決方案:

{% for user in entity.users %} 
    {{ user.name }}{% if not loop.last %} - {% endif %} 
{% endfor %} 

但這不是很優雅。 join過濾器在循環中似乎不太合適。

回答

8

AFAIK,不,您無法使用join過濾器作爲您的使用情況,而沒有解決方法。這是因爲您需要將getName拉出對象屬性。 join只是將Traversable實例的每個元素與給定的glue鏈接起來。

但是,如果您需要它,有一些解決方法。

添加一個__toString方法

在你User的實體,您可以添加一個__toString方法來獲取默認的用戶名。
如果沒有其他對象使用當前的默認toString你應該然而照顧,因爲它可能會導致衝突

namespace Acme\FooBundle\Entity; 

class User 
{ 
    public function __toString() 
    { 
     return $this->getName(); 
    } 
} 

然後你就可以在你的樹枝使用join過濾

{{ entity.users|join(' - ') }} 

地圖中的用戶名控制器

在您的控制器中,在將參數發送到視圖之前,可以映射它們的所有用戶名以適合數組。
注:我假設是PersistentCollection,如果沒有,在你的樹枝使用array_map代替

// Acme/FooBundle/Controller/MyController#fooAction 

$users = $entity->getUsers(); 
$usernames = $users->map(function(User $user) { 
    return $user->getName(); 
}); 

return $this->render('AcmeFooBundle:My:foo.html.twig', array(
    'entity' => $entity, 
    'usernames' => $usernames 
); 

然後

{{ usernames|join(' - ') }} 

創建樹枝過濾

在你的應用程序中,可以創建一個Twig Extension。在這個例子中,我將創建一個名爲joinBy的過濾器,它將通過指定一個用於連接元素的方法來表現爲join

服務聲明

直和輕鬆,沒有太苛刻,但一個標準的聲明像文檔

服務。陽明海運

acme_foo.tools_extension: 
    class: Acme\FooBundle\Twig\ToolsExtension 
    tags: 
     - { name: twig.extension } 

擴展的創建

@Acme \ FooBundle \嫩枝\ ToolsExtension

namespace Acme\FooBundle\Twig; 

use Twig_Extension, Twig_Filter_Method; 
use InvalidArgumentException, UnexpectedValueException; 
use Traversable; 

/** 
* Tools extension provides commons function 
*/ 
class ToolsExtension extends Twig_Extension 
{ 
    /** 
    * {@inheritDoc} 
    */ 
    public function getName() 
    { 
     return 'acme_foo_tools_extension'; 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public function getFilters() 
    { 
     return array(
      'joinBy' => new Twig_Filter_Method($this, 'joinBy') 
     ); 
    } 

    /** 
    * Implode-like by specifying a value of a traversable object 
    * 
    * @param mixed $data Traversable data 
    * @param string $value Value or method to call 
    * @param string $join Join string 
    * 
    * @return string Joined data 
    */ 
    public function joinBy($data, $value, $join = null) 
    { 
     if (!is_array($data) && !($data instanceof Traversable)) { 
      throw new InvalidArgumentException(sprintf(
       "Expected array or instance of Traversable for ToolsExtension::joinBy, got %s", 
       gettype($data) 
      )); 
     } 

     $formatted = array(); 

     foreach ($data as $row) { 
      $formatted[] = $this->getInput($row, $value); 
     } 

     return implode($formatted, $join); 
    } 

    /** 
    * Fetches the input of a given property 
    * 
    * @param mixed $row An array or an object 
    * @param string $find Property to find 
    * @return mixed Property's value 
    * 
    * @throws UnexpectedValueException When no matching with $find where found 
    */ 
    protected function getInput($row, $find) 
    { 
     if (is_array($row) && array_key_exists($find, $row)) { 
      return $row[$find]; 
     } 

     if (is_object($row)) { 
      if (isset($row->$find)) { 
       return $row->$find; 
      } 

      if (method_exists($row, $find)) { 
       return $row->$find(); 
      } 

      foreach (array('get%s', 'is%s') as $indic) { 
       $method = sprintf($indic, $find); 

       if (method_exists($row, $method)) { 
        return $row->$method(); 
       } 
      } 

      if (method_exists($row, $method)) { 
       return $row->$method(); 
      } 
     } 

     throw new UnexpectedValueException(sprintf(
      "Could not find any method to resolve \"%s\" for %s", 
      $find, 
      is_array($row) 
       ? 'Array' 
       : sprintf('Object(%s)', get_class($row)) 
     )); 
    } 
} 

使用

現在,您可以通過調用用它在你的樹枝

{{ entity.users|joinBy('name', ' - ') }} 
# or 
{{ entity.users|joinBy('getName', ' - ') }} 
+0

太好了,謝謝! – ncrocfer

1

在實體類中添加__toString()方法,並且完成。

並使用本機Twig的join過濾器,如在{{ entity.users|join(' - ') }}中那樣。

+0

太棒了!謝謝 – Ld91