2013-01-09 175 views
11

我在Twig模板中有一個循環,它會返回多個值。最重要的是 - 我的參賽作品的ID。當我沒有使用任何框架或模板引擎時,我在循環中只使用了file_exists()。現在,我似乎無法在Twig中找到辦法。Symfony2 - 檢查文件是否存在

當我在標頭中顯示用戶的頭像時,我在控制器中使用了file_exists(),但是我這樣做是因爲我沒有循環。

我在Twig嘗試了defined,但它沒有幫助我。有任何想法嗎?

回答

31

如果你想要檢查一個文件,該文件是不是枝杈模板(如此定義不能工作)的存在,創建一個TwigExtension服務和功能添加file_exists()來樹枝:

的src /的appbundle /嫩枝/分機/ TwigExtension.php

<?php 

namespace AppBundle\Twig\Extension; 

class FileExtension extends \Twig_Extension 
{ 

    /** 
    * Return the functions registered as twig extensions 
    * 
    * @return array 
    */ 
    public function getFunctions() 
    { 
     return array(
      new Twig_SimpleFunction('file_exists', 'file_exists'), 
     ); 
    } 

    public function getName() 
    { 
     return 'app_file'; 
    } 
} 
?> 

註冊您的服務:

的src /的appbundle /資源/配置/ services.yml

# ... 

parameters: 

    app.file.twig.extension.class: AppBundle\Twig\Extension\FileExtension 

services: 

    app.file.twig.extension: 
     class: %app.file.twig.extension.class% 
     tags: 
      - { name: twig.extension } 

就是這樣,現在你可以使用file_exists()樹枝模板中;)

一些template.twig:

{% if file_exists('/home/sybio/www/website/picture.jpg') %} 
    The picture exists ! 
{% else %} 
    Nope, Chuck testa ! 
{% endif %} 

編輯回答您的評論:

要使用file_exists(),你需要指定文件的絕對路徑,所以你需要web目錄的絕對路徑,這樣做可以訪問webpa日在樹枝模板 應用程序/配置/ config.yml:

# ... 

twig: 
    globals: 
     web_path: %web_path% 

parameters: 
    web_path: %kernel.root_dir%/../web 

現在你可以得到一個樹枝模板中的文件的完整物理路徑:

{# Display: /home/sybio/www/website/web/img/games/3.jpg #} 
{{ web_path~asset('img/games/'~item.getGame.id~'.jpg') }} 

所以,你就可以檢查文件是否存在:

{% if file_exists(web_path~asset('img/games/'~item.getGame.id~'.jpg')) %} 
+0

偉大的作品,但你能告訴我,我怎麼能檢查資產的存在呢? –

+0

我認爲這樣: {%if file_exists(asset('images/logo.png'))%}檢查!{%endif%}因爲asset()返回媒體的絕對路徑,所以它可以工作並檢查正確的路徑^^ – Sybio

+0

這就是我想的,但'{%if file_exists(asset('img/games /'〜item.getGame.id〜'.jpg'))%}'不起作用(我的意思是,它返回false,即使文件在那裏)。 –

3

我有和Tomek一樣的問題。我用Sybio的解決方案,並進行了如下修改:

  1. 應用程序/ config.yml =>添加 「/」 在web_path結束

    parameters: 
        web_path: %kernel.root_dir%/../web/ 
    
  2. 呼叫file_exists沒有 「財富」:

    {% if file_exists(web_path ~ 'img/games/'~item.getGame.id~'.jpg') %} 
    

希望這有助於。

+0

我想添加一個參數以便在樹枝模板中使用,您需要將它添加到樹枝配置中,如[這裏]所述(http:// stackoverflow.com/questions/6787895/how-to-get-config-parameters-in-symfony2-twig-templates) – Joe

11

我創建了一個Twig函數,它是我在這個主題上找到的答案的擴展。我的asset_if函數有兩個參數:第一個是資產顯示的路徑。如果第一個資產不存在,第二個參數是後備資產。

創建您的擴展文件:

的src/Showdates/FrontendBundle /嫩枝/分機/ ConditionalAssetExtension.php:

<?php 

namespace Showdates\FrontendBundle\Twig\Extension; 

use Symfony\Component\DependencyInjection\ContainerInterface; 

class ConditionalAssetExtension extends \Twig_Extension 
{ 
    private $container; 

    public function __construct(ContainerInterface $container) 
    { 
     $this->container = $container; 
    } 

    /** 
    * Returns a list of functions to add to the existing list. 
    * 
    * @return array An array of functions 
    */ 
    public function getFunctions() 
    { 
     return array(
      'asset_if' => new \Twig_Function_Method($this, 'asset_if'), 
     ); 
    } 

    /** 
    * Get the path to an asset. If it does not exist, return the path to the 
    * fallback path. 
    * 
    * @param string $path the path to the asset to display 
    * @param string $fallbackPath the path to the asset to return in case asset $path does not exist 
    * @return string path 
    */ 
    public function asset_if($path, $fallbackPath) 
    { 
     // Define the path to look for 
     $pathToCheck = realpath($this->container->get('kernel')->getRootDir() . '/../web/') . '/' . $path; 

     // If the path does not exist, return the fallback image 
     if (!file_exists($pathToCheck)) 
     { 
      return $this->container->get('templating.helper.assets')->getUrl($fallbackPath); 
     } 

     // Return the real image 
     return $this->container->get('templating.helper.assets')->getUrl($path); 
    } 

    /** 
    * Returns the name of the extension. 
    * 
    * @return string The extension name 
    */ 
    public function getName() 
    { 
     return 'asset_if'; 
    } 
} 

註冊服務(app/config/config.ymlsrc/App/YourBundle/Resources/services.yml):

services: 
    showdates.twig.asset_if_extension: 
     class: Showdates\FrontendBundle\Twig\Extension\ConditionalAssetExtension 
     arguments: ['@service_container'] 
     tags: 
      - { name: twig.extension } 

現在在你的模板中使用它:

<img src="{{ asset_if('some/path/avatar_' ~ app.user.id, 'assets/default_avatar.png') }}" /> 
0

只加一點評論西爾維奧的貢獻:自1.12版本

的Twig_Function_Function類已被棄用, 將在2.0被刪除。改用Twig_SimpleFunction。

我們必須Twig_SimpleFunction更改類Twig_Function_Function:

<?php 

namespace Gooandgoo\CoreBundle\Services\Extension; 

class TwigExtension extends \Twig_Extension 
{ 

    /** 
    * Return the functions registered as twig extensions 
    * 
    * @return array 
    */ 
    public function getFunctions() 
    { 
     return array(
      #'file_exists' => new \Twig_Function_Function('file_exists'), // Old class 
      'file_exists' => new \Twig_SimpleFunction('file_exists', 'file_exists'), // New class 
     ); 
    } 

    public function getName() 
    { 
     return 'twig_extension'; 
    } 
} 

的代碼的其餘部分仍然完全一樣說Sybio工作。

0

在sybio的回答中,Twig_simple_function在我的版本中不存在,這裏沒有任何內容適用於外部圖像。所以,我的文件擴展名的文件是這樣的:

namespace AppBundle\Twig\Extension; 

class FileExtension extends \Twig_Extension 
{ 
/** 
* {@inheritdoc} 
*/ 

public function getName() 
{ 
    return 'file'; 
} 

public function getFunctions() 
{ 
    return array(
     new \Twig_Function('checkUrl', array($this, 'checkUrl')), 
    ); 
} 

public function checkUrl($url) 
{ 
    $headers=get_headers($url); 
    return stripos($headers[0], "200 OK")?true:false; 
}