14

Twigテンプレートにループがあり、複数の値を返します。最も重要なのは、私のエントリのIDです。フレームワークもテンプレートエンジンも使用しなかったときは、単にfile_exists()ループ内で使用していました。今、私はTwigでそれを行う方法を見つけることができないようです。

ユーザーのアバターをヘッダーに表示するときfile_exists()はコントローラーで使用しますが、ループがないので表示します。

Twigで試しdefinedましたが、役に立ちません。何か案は?

4

6 に答える 6

33

Twigテンプレートではない(定義されたものは機能しない)ファイルの存在を確認したい場合は、TwigExtensionサービスを作成し、file_exists()関数をtwigに追加します。

src/AppBundle/Twig/Extension/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/Resources/config/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ディレクトリの絶対パスが必要です。これを行うには、twigテンプレートapp / config/config.ymlのWebパスにアクセスできます。

# ...

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')) %}
于 2013-01-09T09:41:35.777 に答える
11

このトピックで見つけた回答の拡張であるTwig関数を作成しました。私のasset_if関数は2つのパラメーターを取ります。最初のパラメーターは、アセットを表示するためのパスです。最初のアセットが存在しない場合、2番目のパラメーターはフォールバックアセットです。

拡張ファイルを作成します。

src / Showdates / FrontendBundle / Twig / Extension / 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.ymlまたはsrc/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') }}" />
于 2013-12-17T20:49:28.630 に答える
3

私はトメックと同じ問題を抱えていました。私はSybioのソリューションを使用し、次の変更を加えました。

  1. app / 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') %}
    

お役に立てれば。

于 2013-03-19T13:26:59.323 に答える
1

SF4、autowire、autoconfigureを使用した私の解決策は次のとおりです。

namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
use Symfony\Component\Filesystem\Filesystem;

class FileExistsExtension extends AbstractExtension
{
    private $fileSystem;
    private $projectDir;

    public function __construct(Filesystem $fileSystem, string $projectDir)
    {
        $this->fileSystem = $fileSystem;
        $this->projectDir = $projectDir;
    }

    public function getFunctions(): array
    {
        return [
            new TwigFunction('file_exists', [$this, 'fileExists']),
        ];
    }

    /**
     * @param string An absolute or relative to public folder path
     * 
     * @return bool True if file exists, false otherwise
     */
    public function fileExists(string $path): bool
    {
        if (!$this->fileSystem->isAbsolutePath($path)) {
            $path = "{$this->projectDir}/public/{$path}";
        }

        return $this->fileSystem->exists($path);
    }
}

services.yaml内:

services:
    App\Twig\FileExistsExtension:
        $projectDir: '%kernel.project_dir%'

テンプレートの場合:

# Absolute path
{% if file_exists('/tmp') %}
# Relative to public folder path
{% if file_exists('tmp') %}

私はSymfonyを初めて使用するので、すべてのコメントを歓迎します。

また、最初の質問はSymfony 2に関するものなので、私の答えは関係がないので、新しい質問をして自分で答えたほうがいいでしょうか?

于 2019-02-14T17:01:59.740 に答える
0

Sybioの貢献に少しコメントを追加してください:

Twig_Function_Functionクラスは、バージョン1.12以降非推奨であり、2.0で削除される予定です。代わりにTwig_SimpleFunctionを使用してください。

クラスTwig_Function_FunctionをTwig_SimpleFunctionで変更する必要があります。

<?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が言ったとおりに機能します。

于 2015-11-06T10:49:58.410 に答える
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;
}
于 2016-06-15T11:23:03.523 に答える