Can't get assetic to cssrewrite prod images properly - css

Using Symfony and Assetic I cannot get css images to 'dump' correctly in my prod environment.
They continue to link back to the web/bundle/...etc.. location.
I have a very basic cssrewrite setup:
# Assetic Configuration
assetic:
debug: "%kernel.debug%"
use_controller: false
filters:
cssrewrite:
#closure:
# jar: "%kernel.root_dir%/Resources/java/compiler.jar"
#yui_css:
# jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"
My template:
{% stylesheets 'bundles/<my bundle>/css/style.css' filter='cssrewrite' %}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}
I have the prod version of app.php in place with debug false:
use Symfony\Component\ClassLoader\ApcClassLoader;
use Symfony\Component\HttpFoundation\Request;
$loader = require_once __DIR__.'/../app/bootstrap.php.cache';
// Use APC for autoloading to improve performance.
// Change 'sf2' to a unique prefix in order to prevent cache key conflicts
// with other applications also using APC.
/*
$apcLoader = new ApcClassLoader('sf2', $loader);
$loader->unregister();
$apcLoader->register(true);
*/
require_once __DIR__.'/../app/AppKernel.php';
//require_once __DIR__.'/../app/AppCache.php';
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
//$kernel = new AppCache($kernel);
// When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
//Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
I have done:
app/console assets:install --symlink
All seems fine
Then I clear the prod cache
OK
app/console assetic:dump --env=prod
My css and js copy out with the expected file names, however I still have url('../../bundle/..etc../images/bg.png'); appearing in my css
In the symlinked version the css is: url('../images/bg.png');
So it must be something to do with assetic.
What I expect is for the 'dump'ed css to contain links like url('../images/bg.png');
And for the images themselves to be copied out to web/images/123abc.png
Should I expect this from assetic and if so what am I doing wrong?
Thanks, in advance.

// In Config.yml file
# Assetic Configuration
assetic:
debug: "%kernel.debug%"
use_controller: false
bundles: [ ]
In app.php file
//If it is in dev environment In your app_dev.php file contain like this
$kernel = new AppKernel('prod', true);
$kernel->loadClassCache();
// If it is in prod environment, In your app.php file contain like this
$kernel = new AppKernel('prod', true);
$kernel->loadClassCache();

Related

Symfony asset function prepends / to http url

I've tried to add webpack to a Symfony 3.1 app. The problem is, when I add HMR, the asset function doesn't resolve correctly
// base.html.twig
<script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
// app/config/config_dev.yml
framework:
assets:
base_path: "http://localhost:8080"
Result: <script src="/http://localhost:8080/bundles/fosjsrouting/js/router.js"></script>
How can I tell Symfony to not prepend the starting / if the base_path begins with http://?
You can use base_urls. Protocol/host/port should not be used in base_path for assets.
https://symfony.com/doc/current/reference/configuration/framework.html#assets

Which file should I override to change edit form template in Sonata Admin?

I follow this tutorial to add a preview of my image file in my sonata admin (symfony3)
http://symfony.com/doc/current/bundles/SonataAdminBundle/cookbook/recipe_image_previews.html
But I not being able to add the CSS parte. The image is too large.
Should I override one of the sonata templates for it? If yes, which file I change and how do I do it? [I'm pretty new in sonata/symfony3]
If not, how should I add the css file in the project?
My actual code is exactly as the tutorial:
class ImageAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
// get the current Image instance
$image = $this->getSubject();
// use $fileFieldOptions so we can add other options to the field
$fileFieldOptions = array('required' => false);
if ($image && ($webPath = $image->getWebPath())) {
// get the container so the full path to the image can be set
$container = $this->getConfigurationPool()->getContainer();
$fullPath = $container->get('request')->getBasePath().'/'.$webPath;
// add a 'help' option containing the preview's img tag
$fileFieldOptions['help'] = '<img src="'.$fullPath.'" class="admin-preview" />';
}
$formMapper
// ... other fields ...
->add('file', 'file', $fileFieldOptions)
;
}
// ...
}
You'll need to add some code to include a CSS file in your Symfony project. Something similar to
{% stylesheets 'bundles/app/css/*' filter='cssrewrite' %}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
Then you'd put the following CSS from the tutorial into that file.
img.admin-preview {
max-height: 200px;
max-width: 200px;
}
You can learn more about including CSS files with Symfony here.
First you need to make a template that extends SonataAdminBundle:CRUD:base_edit.html.twig, here is an example:
{# BlastBaseEntitiesBundle:CRUD:edit.html.twig #}
{% extends 'SonataAdminBundle:CRUD:base_edit.html.twig' %}
{# ... #}
Then create your css file in Resources/Public/css.
Execute the command bin/console assets:install to publish your stylesheet to the web/bundles directory.
{# blastcore/css corresponds to BlastCoreBundle/Resources/Public/css and web/bundles/blastcore/js #}
<link rel="stylesheet" href="{{ asset(blastcore/css/style.css) }}" />
http://symfony.com/doc/current/assetic/asset_management.html
Now you need to tell sonata to use your template for your admin.
you can do that in the service definition :
admin.yml
blast_base_entities.admin.search_index_entity:
class: Blast\BaseEntitiesBundle\Admin\SearchIndexEntityAdmin
arguments: [~, Blast\BaseEntitiesBundle\Entity\SearchIndexEntity, BlastCoreBundle:CRUD]
tags:
- name: sonata.admin
manager_type: orm
group: admin
label: SearchIndexEntity
calls:
- [ setTemplate, [edit, BlastBaseEntitiesBundle:CRUD:edit.html.twig]]
https://sonata-project.org/bundles/admin/master/doc/reference/templates.html#crudcontroller-actions-templates

Symfony 3 - in prod, assetic works fine with "AppKernel('prod', true)", not with "AppKernel('prod', false)"

in prod mode, everything is working with this configuration (app.php):
<?php
use Symfony\Component\HttpFoundation\Request;
/** #var \Composer\Autoload\ClassLoader $loader */
$loader = require __DIR__.'/../app/autoload.php';
include_once __DIR__.'/../var/bootstrap.php.cache';
$kernel = new AppKernel('prod', true);
$kernel->loadClassCache();
//$kernel = new AppCache($kernel);
// When using the HttpCache, you need to call the method in your front controller instead of relying on the configuration parameter
//Request::enableHttpMethodParameterOverride();
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
When i turn "$kernel = new AppKernel('prod', false);" to false, the display does not work fully.
This is my config.yml (for assetic):
# ASSETIC BUNDLE
assetic:
debug: '%kernel.debug%'
use_controller: '%kernel.debug%'
filters:
cssrewrite: ~
I always do this:
- pbc cache:clear --env=prod --no-debug
- pbc assetic:dump --env=prod --no-debug
(alias pbc for php bin/console)
If I inspect the code, i can see all .css are not dump:
<head>
....
<link rel="stylesheet" href="/css/compiled/app.css">
<link rel="stylesheet" href="/css/compiled/user.css">
....
</head>
Because when AppKernel is set to true, i can see that:
<head>
.....
<link rel="stylesheet" href="/css/compiled/app_bootstrap.min_1.css">
<link rel="stylesheet" href="/css/compiled/app_dataTables.bootstrap.min_2.css">
<link rel="stylesheet" href="/css/compiled/app_font-awesome_3.css">
<link rel="stylesheet" href="/css/compiled/app_custom_front_4.css">
<link rel="stylesheet" href="/css/compiled/app_header_5.css">
<link rel="stylesheet" href="/css/compiled/app_footer_6.css">
<link rel="stylesheet" href="/css/compiled/user_user_1.css">
<link rel="stylesheet" href="/css/compiled/user_select2.min_2.css">
.....
</head>
I know that i can't set AppKernel to true in prod mode, so it's very important to fix this problem. I read a lot of topic but i don't find the solution...
Any idea?
Thanks
I had the same issue.
deleted cache directories in
/home/[user]/www/[site]/var/cache
and it works fine
the problem occured when migrated to another server

assetic and filters

I try to use the cssembed filter loading my stylesheets (because of the images referenced in the css)
In config.yml
assetic:
debug: %kernel.debug%
use_controller: false
bundles: [ cramifviewkitBundle ]
#java: /usr/bin/java
filters:
cssrewrite: ~
cssembed:
jar: %kernel.root_dir%/Resources/java/cssembed-0.4.5.jar
yui_css:
jar: %kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar
yui_js:
jar: %kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar
I download cssembed-0.4.5.jar and located it in src/my_bundle/Resources/java
in the template I wrote :
{% stylesheets
'#myBundle/Resources/public/css/*'
'#myBundle/Resources/public/JQMenu/css/*'
filter='cssembed'
%}
Everything is fine for the first import, but for the second one, when I look with firebug, I have this :
<link type="text/css" href="/viewkit/web/app_dev.php/css/eb2d30c_part_1_jqueryMenus_1.css" rel="stylesheet">
and when I open it, it is not css but html because there is an error :
<h1>Exception thrown when handling an exception (Symfony\Component\HttpKernel\Exception\FlattenException: Warning: json_encode() [<a href='function.json-encode'>function.json-encode</a>]: Invalid UTF-8 sequence in argument in C:\wamp\www\viewkit\vendor\monolog\monolog\src\Monolog\Formatter\NormalizerFormatter.php line 99)</h1>
<div class="block_exception clear_fix">
<h2><span>1/1</span> <abbr title="ErrorException">ErrorException</abbr>: Warning: json_encode() [<a href='function.json-encode'>function.json-encode</a>]: Invalid UTF-8 sequence in argument in C:\wamp\www\viewkit\vendor\monolog\monolog\src\Monolog\Formatter\NormalizerFormatter.php line 99</h2>
</div>
<div class="block">
<ol class="traces list_exception">
<li> in C:\wamp\www\viewkit\vendor\monolog\monolog\src\Monolog\Formatter\NormalizerFormatter.php line 99</li>
any idea where it could come from ?
Put the cssembed-0.4.5.jar in app/Resources/java directory as you specified in the configuration.

How to combine these assetics in Symfony2?

I'm using ExposeTranslationBundle (expose translations to javascript) and JMSI18nRoutingBundle (expose routes to javascript). This is part of my <head> tag:
{% javascripts filter='?yui_js' output='js/app.js'
'../app/Resources/public/js/jquery-*.js'
'../app/Resources/public/js/jquery/*'
'../app/Resources/public/js/app.js'
'bundles/fosjsrouting/js/router.js'
'bundles/bazingaexposetranslation/js/translation.js' %}
<script src="{{ asset_url }}" ></script>
{% endjavascripts %}
<!-- ExposeTranslationBundle and JMSI18nRoutingBundle -->
<script src="{{ path('fos_js_routing_js',
{"callback": "fos.Router.setData"}) }}"></script>
<script src="{{ url('bazinga_exposetranslation_js') }}"></script>
Is possible to combine the last two <script> imports into first assetic and how?
I thing it is not possible because the FOSJSRouting javascript file is generated by a controller. Internaly the bundles caches the js but in app/cache, so it needs to go through the controller every request. I'm not familiar with the expose translation bundle but I guess it's the same problem here.
There has been an ongoing discussion in the issue tracke of FOSJsRouterBundle on github and there is also a sollution. See the full issue here: https://github.com/FriendsOfSymfony/FOSJsRoutingBundle/issues/22
The workaround is to have a script or command to dump the output to files in web/js directory:
<?php
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
use Symfony\Component\HttpFoundation\Request;
$kernel = new AppKernel('stage', false);
$kernel->loadClassCache();
$response = $kernel->handle(Request::create('/js/routing?callback=fos.Router.setData'));
file_put_contents(__DIR__.'/../web/js/routes.js', $response->getContent());
This is somewhat of a workaround sollution. I've been thinking about implementing a generic bundle wich whome this task can be configured for several other bundles using controllers to output js. The controller actions would have to be configured in a yml file and then a command would have have to be executed at each deployment/modification of routes/strings. But I havn't had time for this... yet ;)
Instead of import, you could happily put it inline, ie:
<script type="text/javascript">
{# BazingaExposeTranslation #}
{% render 'bazinga.exposetranslation.controller:exposeTranslationAction'
with { domain_name: "messages", _locale:app.session.locale, _format: "js" } %}
{# JMSI18nRoutingBundle ... #}
</script>
You need to check the routing file for those bundles.

Resources