使用资产覆盖资产

时间:2015-02-24 10:21:25

标签: php twig assetic

我有一个使用来自不同源文件夹的资源的项目。其中一些资产可能会覆盖其他资产。我想在树枝模板中引用资产。如果资源存在于多个源文件夹中,则应选择第一个(例如,设计图像将覆盖模块图像)。我打算使用kriswallsmith/assetic包,但找不到任何指定多个根文件夹的方法。 我想要的是Twig_Loader_Filesystem::addPath,但是对于资产。

示例:

源文件夹:

  • assets/design(除了其他资源包含images/red.jpg
  • assets/module(除了其他资源包含images/red.jpg

在我要引用的树枝模板中

{% image 'images/red.jpg' %}<img src="{{ asset_url }}" />{% endimage %}

图书馆现在应该选择图片assets/design/images/red.jpg

资产库是否可以实现? 如果我需要扩展任何课程,你能给我一些指示吗? 还是有另一个图书馆可以更好地满足我的需求吗?

1 个答案:

答案 0 :(得分:0)

好吧,我意识到如何解决我的问题:

我必须扩展AssetFactory并覆盖parseInput方法。我提出了以下解决方案:

use Assetic\Asset\AssetInterface;
use Assetic\Factory\AssetFactory;

class MyAssetFactory extends AssetFactory
{
    /**
     * @var string[]
     */
    private $rootFolders;

    /**
     * @param string[] $rootFolders
     * @param bool   $debug
     */
    public function __construct($rootFolders, $debug = false)
    {
        if (empty($rootFolders)) {
            throw new \Exception('there must be at least one folder');
        }

        parent::__construct($rootFolders[0], $debug);

        $this->rootFolders = $rootFolders;
    }

    /**
     * @param string $input
     * @param array  $options
     * @return AssetInterface an asset
     */
    protected function parseInput($input, array $options = array())
    {
        // let the parent handle references, http assets, absolute path and glob assets
        if ('@' == $input[0] || false !== strpos($input, '://') || 0 === strpos($input, '//') || self::isAbsolutePath($input) || false !== strpos($input, '*')) {
            return parent::parseInput($input, $options);
        }

        // now we have a relatve path eg js/file.js
        // let's match it with the given rootFolders
        $root = '';
        $path = $input;
        foreach ($this->rootFolders as $root) {
            if (file_exists($root . DIRECTORY_SEPARATOR . $input)) {
                $path = $input;
                $input = $root . $path;
                break;
            }
        }

        // TODO: what to do, if the asset was not found..?

        return $this->createFileAsset($input, $root, $path, $options['vars']);
    }

    /**
     * copied from AssetFactory, as it was private
     *
     * @param string $path
     * @return bool
     */
    private static function isAbsolutePath($path)
    {
        return '/' == $path[0] || '\\' == $path[0] || (3 < strlen($path) && ctype_alpha($path[0]) && $path[1] == ':' && ('\\' == $path[2] || '/' == $path[2]));
    }
}

现在我可以使用不同的源文件夹创建一个新工厂。

$factory = new MyAssetFactory(array('/folder/alpha/', '/folder/beta/'));
// $factory->set some stuff
$twig->addExtension(new AsseticExtension($factory));