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
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
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
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
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.
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.