Возможно ли использовать Symfony2 в файле assets_version ?
Мы используем assets_version и assets_version_format для управления версией файлов и принудительного обновления кеша в кэше CDN и браузера.
Это работает как шарм !, но мы обнаружили, что для всех используемых статических ресурсов есть только один параметр assets_version
.
Это проблема, так как наш webapp, имеет много статических ресурсов, и мы ежедневно развертываем изменения в среде prod. Эта ситуация убивает кеш. 🙁
Это наша текущая конфигурация:
config.yml
framework: templating: engines: ['twig'] assets_version: %assets_version% assets_version_format: "stv%%2$s/%%1$s" # Assetic Configuration assetic: debug: %kernel.debug% use_controller: false # java: /usr/bin/java filters: cssrewrite: ~ closure: jar: %kernel.root_dir%/java/compiler.jar yui_css: jar: %kernel.root_dir%/java/yuicompressor-2.4.6.jar
sometemplate.html.twig
{% stylesheets 'bundles/webapp/css/funCommon.css' 'bundles/webapp/css/funMobile.css' filter='?yui_css' %} <link rel=stylesheet href='{{ asset_url }}'> {% endstylesheets %} {% javascripts 'bundles/webapp/js/app.js' 'bundles/webapp/js/utils.js' filter='?closure' %} <script src="{{ asset_url }}"></script> {% endjavascripts %} {% javascripts 'bundles/webapp/js/moduleX.js' 'bundles/webapp/js/utilsX.js' filter='?closure' %} <script src="{{ asset_url }}"></script> {% endjavascripts %}
Когда я изменяю любой файл css или модуль JS или любой другой файл, все пути изменяются .
Я хотел бы управлять параметром версии assets_version_format параметром твига javascript / stylesheet.
Это то, что я ищу:
{% javascripts 'bundles/webapp/js/app.js' 'bundles/webapp/js/utils.js' filter='?closure' **version='XX'** %} <script src="{{ asset_url }}"></script> {% endjavascripts %}
После многодневного поиска я нашел вариант пакетов на AsseticBundle
http://symfony.com/doc/2.0/reference/configuration/framework.html#full-default-configuration
Используя этот вариант конфигурации, я мог бы сделать что-то вроде этого:
{% javascripts file package='packageName' %}
или
{{asset(file,packageName)}}
config.yml
framework: templating: engines: ['twig'] assets_version: %assets_version% assets_version_format: "stv%%2$s/%%1$s" packages: css: version: 6.1 version_format: "stv%%2$s/%%1$s" jsApp: version: 4.2 version_format: "stv%%2$s/%%1$s"
sometemplate.html.twig
<link rel=stylesheet href='{{ asset('bundles/webapp/css/funCommon.css','css') }}'> {% javascripts 'bundles/webapp/js/app.js' 'bundles/webapp/js/utils.js' filter='?closure' package='jsApp' %} <script src="{{ asset_url }}"></script> {% endjavascripts %}
Результатом этого является:
<link rel=stylesheet href="http://static.domain.com/stv6.1/css/HASH.css"> <script src="http://static.domain.com/stv4.2/js/HASH.js"></script>
Для меня это был самый простой способ управлять версиями активов по файлу.
Если вы пытаетесь использовать параметр assets_version с помощью помощников javascripts или stylesheets , вам все равно необходимо использовать вспомогательный помощник.
{% javascripts 'bundles/webapp/app.js' 'bundles/webapp/utils.js' filter='?closure' %} <script src="{{ asset(asset_url) }}" type="text/javascript"></script> {% endjavascripts %}
Он автоматически не добавляется в asset_url (что хорошо).
Легкое и быстрое обходное решение выглядит примерно так:
{% set asset_version = 'xyz' %} {% javascripts 'bundles/webapp/js/app.js' 'bundles/webapp/js/utils.js' filter='?closure' %} <script src="{{ asset_url }}?{{ asset_version }}"></script> {% endjavascripts %}
Но вам может понадобиться переместить логику на расширение ветки, получая asset_url в качестве аргумента.
Обычной процедурой было бы генерировать хэши файлов, которые затем будут храниться в кеше пользователя.
Затем вы можете сравнить все хэши с их текущими в пользовательской команде и добавить последний хэш или что-то еще к имени файла, чтобы принудительно обновить кеш.
Следующее решение добавит метку времени вместо номера версии. Важная часть заключается в том, что временная метка времени будет изменяться только при очистке кеша.
Сначала создайте пропуск компилятора:
<?php namespace App\Bundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\DefinitionDecorator; /** * Created by PhpStorm. * User: hpenny * Date: 15/03/17 * Time: 2:33 PM */ class AssetCompilerPass implements CompilerPassInterface { /** * You can modify the container here before it is dumped to PHP code. * * @param ContainerBuilder $container */ public function process(ContainerBuilder $container) { $container->removeDefinition('assets._version__default'); $decorator = new DefinitionDecorator('assets.static_version_strategy'); $decorator->replaceArgument(0, time()); $container->setDefinition('assets._version__default', $decorator); } }
Затем добавьте его в свой основной пакет:
namespace App\Bundle; use App\Bundle\DependencyInjection\Compiler\AssetCompilerPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; class AppBundle extends Bundle { public function build(ContainerBuilder $container) { parent::build($container); $container->addCompilerPass(new AssetCompilerPass()); } }
Это будет работать только с пакетом активов по умолчанию. Вам нужно будет выполнить различные определения пакетов, которые вы настроили, если используете эту функцию.
Вам нужно будет заменить assets._version_<package name>
вместо assets._version__default