Symfony and basic css - php

I just started to use symfony to make a website. I'm really new to this but still with internet and all the documentation i manage to understand how it basically work and i figured out how to use the assets for my css code on symfony. I've got my asset configured with the entry and everything else seems to work. Even my public dir seems to be ok. Now when i tried to write some css it doesn't seems to load on my home page :/. Can someone help me with this ? Thanks for your help ! :)
HERE'S MY WEBPACK.CONFIG.JS
// directory where compiled assets will be stored
.setOutputPath('public/build')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or sub-directory deploy
//.setManifestKeyPrefix('build/')
/*
* ENTRY CONFIG
*
* Add 1 entry for each "page" of your app
* (including one that's included on every page - e.g. "app")
*
* Each entry will result in one JavaScript file (e.g. app.js)
* and one CSS file (e.g. app.css) if your JavaScript imports CSS.
*/
//.addEntry('app', './assets/js/app.js')
//.addEntry('page1', './assets/js/page1.js')
//.addEntry('page2', './assets/js/page2.js')
.addEntry('style', './assets/css/app.css')
HERE'S MY BASE.TWIG.HTML FILE
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
{% block stylesheets %}<link rel="stylesheet" href="{{ asset('/build/css/style.css') }}">{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>
HERE'S THE HEAD OF THE PAGE WHERE I WANT TO APPLY THE CSS ON
{% extends 'base.html.twig' %}
{% block body%}
<h1>welcome</h1>
<img src="" alt="Home pic" class="bckPic">
<!-- About -->
<h2 class="headTitle">About</h2>
<div class="row">
<p class="col">blablablablablabla</p>
<img class="col" src="" alt="logo">
</div>

Your code seem to be correct.
Try to change
`<link rel="stylesheet" href="{{ asset('/build/css/style.css') }}">`
with
{{ encore_entry_link_tags('style') }}
"style" is entry name in your webpack.config.js -> .addEntry('style', './assets/css/app.css')
Then in command line go to source root folder and run:
yarn install
#for develop env
yarn encore dev
#for prod env
#yarn encore prod
and refresh page
See: https://symfony.com/doc/current/frontend/encore/installation.html

Related

CSS and javascript not working in Symfony project

I recently started a new project in Symfony and I did everything here
but it didn't help.
I work for first time with Symfony and this is my first project. I strictly follow the documentation and I am trying to add some CSS but its now working. I use Encore and downloaded Yarn as the documentation says to do.
Below I will upload some of my code. It seems fine but it's not.
html.twig
<!DOCTYPE html>
<html lang="en" xmlns:th="http:thymeleaf.org">
<head>
<title>Events & People</title>
<meta charset="UTF-8">
{% block stylesheets %}
{#{% stylesheets '#AppBundle/public/build/app.css' %}#}
{{ encore_entry_link_tags('app') }}
<link src="/build/app.css" rel="stylesheet"/>
{#{% endstylesheets %}#}
{% endblock %}
</head>
webpack.config.js
var Encore = require('#symfony/webpack-encore');
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or sub-directory deploy
//.setManifestKeyPrefix('build/')
/*
* ENTRY CONFIG
*
* Add 1 entry for each "page" of your app
* (including one that's included on every page - e.g. "app")
*
* Each entry will result in one JavaScript file (e.g. app.js)
* and one CSS file (e.g. app.css) if you JavaScript imports CSS.
*/
.addEntry('app', './assets/js/app.js')
//.addEntry('page1', './assets/js/page1.js')
//.addEntry('page2', './assets/js/page2.js')
// will require an extra script tag for runtime.js
// but, you probably want this, unless you're building a single-page app
.enableSingleRuntimeChunk()
/*
* FEATURE CONFIG
*
* Enable & configure other features below. For a full
* list of features, see:
* https://symfony.com/doc/current/frontend.html#adding-more-features
*/
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
// enables hashed filenames (e.g. app.abc123.css)
.enableVersioning(Encore.isProduction())
//11111111111
// .enableSassLoader()
//
// // processes files ending in .less
// .enableLessLoader()
//
// // processes files ending in .styl
// .enableStylusLoader()
//11111111111
// enables Sass/SCSS support
//.enableSassLoader()
// uncomment if you use TypeScript
//.enableTypeScriptLoader()
// uncomment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
;
module.exports = Encore.getWebpackConfig();
Here is an image of my tree of files:
If it's done right it should load the files from my /build/app.css, but it's not loading it.
For me, it was just a caching problem.
let's try to delete the cache.
I didn't search deeply, but one bad think is your link tag...
Replace (src by href)
<link src="/build/app.css" rel="stylesheet"/>
By
<link href="/build/app.css" rel="stylesheet"/>
Have you tried this:
<link src="build/app.css" rel="stylesheet"/>
removing the leading "/" only and see if that works? not certain though.
I solved my problem I just have an error in my CSS and yarn didn't compile it
Move your link tag outside of the stylesheet block's. And use twig asset() function instead of the absolute path.
PS: use href instead of src in link tag
<!DOCTYPE html>
<html lang="en" xmlns:th="http:thymeleaf.org">
<head>
<title>Events & People</title>
<meta charset="UTF-8">
<link href="{{ asset('build/app.css') }}" type="text/css" rel="stylesheet"/>
{% block stylesheets %} {% endblock %}
</head>
If you really want the place the link tag inside your stylesheet block's, you must call this by using twig parent() function's in each template view
{% extends 'base.html.twig' %}
{% block stylesheets %}
{# call the parent content inside stylesheet block #}
{{ parent() }}
{# other css code here #}
{% endblock %}
the script & stylesheets should be outside the body tag like this!
> <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
</head>
<body>
{% block body %}{% endblock %}
</body>
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
</html>
The script and stylesheets should be outside the body tag, like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
</head>
<body>
{% block body %}{% endblock %}
</body>
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
</html>

Include function in Twig template Symfony

Hello Guys I'm new to symfony and twig and what i'm trying to achiv is this:
In my base.html.twig file I try to include('article.html.twig') all works fine until I try to override(extend) the stylesheets block that resides in base.html.twig from article.html.twig.
I get an error message that this can only be achived if I extend base.html.twig (I know it works like that but its not what I want)
I want in fact to attach to article.html.twig the css and the javascript related to the html in this template and that they only get linked (loaded by the browser) in the section of the page whenever I include the template in any other template. It should work like a standalone component (webpart) or whatever this is called.
Do any of you know if such a thing is possible?
Thanks in advance.
Here is the base.html.twig:
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
{% block stylesheets %}
<link rel="stylesheet" type="text/css" media="all" href="{{ asset('style.css') }}" />
{% endblock %}
</head>
<body>
<p>Test include:</p>
{{ include('article.html.twig') }}
</body>
Here is the article.html.twig
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" type="text/css" media="all" href="{{ asset('custom.css') }}" />
{% endblock %}
<div id="article">
This is an Article!
</div>
Sorry, I just read your question again, and now I fully understand what you are trying to achieve.
Unfortunately it is not possible to override a block from within an include. It's exactly like the error message already states... It is only possible to override a block if you extend the original template.

symfony 2 template inheritance and assets management in multi app environment

I have a problem,
An exception has been thrown during the rendering of a template ("Unable to generate a URL for the named route "_assetic_3625095_0" as such route does not exist.") in #base_templates/base.html.twig at line 9.
Sturcture of my app directory:
Resources // Contains common layouts and assets for all of my apps
config // Contains common configs
current_app // yes, this is a current application directory
So. I have a base.html.twig in my Rosurces/views/ directory with such markup:
<html>
<head>
<meta charset="UTF-8"/>
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}"/>
{% block javascripts %}
{% javascripts
'#jquery'
'#global' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
And my current_app/Resources/views/base.html.twig inherit this Resources/views/base.html.twig
And I experience that problem I was talking about in the beginning.
Has anyone experienced such kind of problems already ? Do you have a solution ?
I know if I put javascripts code block inside my current_app/Resources/views/base.html.twig it works, but I need to keep common javascripts inside common layout. And I don't want to use symlink

Symfony2: How to properly include assets in conjunction with Twig template inheritance?

I'm currently developing a web application using Symfony 2.1.0.
I've read through the Templating chapter of the book and I'm trying to include assets (right now, it's just a single stylesheet) in my web pages.
I'm using the Three-level inheritance system that is mentioned in the book, and my application structure currently looks like this:
app/Resources/views/
base.html.twig: base template, containing title, stylesheets and body blocks.
src/My/PageBundle/Resources/views
layout.html.twig: layout template (extending the base template), appending the main stylesheet to the stylesheet block, and overwriting the body block, including navigation.html.twig and defining a content block
layout-admin.html.twig: same thing as above, but including navigation-admin.html.twig
src/My/PageBundle/Resources/views/Main
standard templates, extending the layout template and overwriting its content block
src/My/PageBundle/Resources/views/Administration
administration templates. Same thing as above, but extending the administration layout template.
src/My/PageBundle/Resources/public/css
main.css: main stylesheet
As you can see, I have put the stylesheet in my bundle. I don't know whether this is good practice or not.
Now, the thing is, in layout.html I added this:
{% block stylesheets %}
{{ parent() }}
<link rel="stylesheet" type="text/css" href="{{ asset('css/main.css)' }}" />
{% endblock %}
But asset('css/main.css') is just linking to /css/main.css, whereas ./app/console assets:install installs the assets in web/bundles/mypagebundle/. I don't like the fact that this way, my bundle name would be publicly visible (which could make users suspect I'm using Symfony, and I like keeping the internals of my webpage, well, internal). Is it possible to change the directory where assets:install would install the assets? It seems tedious to me to manually install the assets in web/.
I'm also thinking about using Assetic for asset management, as I personally like the possibility to automatically minify my scripts/stylesheets and store them all together in one file. However, I hear that this is not possible if you include stylesheets at different levels, i.e. it wouldn't work with the three-level inheritance system. Is it possible to work around that? Also, would using Assetic enable me to hide my bundle name from the public?
Using assetic would address all your issues.
I hear that this is not possible if you include stylesheets at different levels, i.e. it wouldn't work with the three-level inheritance system
You can, but it will generate a css file for each level (just like with asset(), actually).
Example:
layout:
{% block stylesheets %}
{{ parent() }}
{% stylesheets 'main.css' %}
<link rel="stylesheet" type="text/css" href="{{ asset_url }}" />
{% endstylesheets %}
{% endblock %}
sub-template:
{% block stylesheets %}
{{ parent() }}
{% stylesheets 'sub.css' %}
<link rel="stylesheet" type="text/css" href="{{ asset_url }}" />
{% endstylesheets %}
{% endblock %}
result:
<link rel="stylesheet" type="text/css" href="..." />
<link rel="stylesheet" type="text/css" href="..." />
Alternatively sub-template can completly override the stylesheets block, so that only one stylesheet is generated (but it's less dry):
{% block stylesheets %}
{% stylesheets 'main.css' 'sub.css' %}
<link rel="stylesheet" type="text/css" href="{{ asset_url }}" />
{% endstylesheets %}
{% endblock %}
result (in production / non debug):
<link rel="stylesheet" type="text/css" href="..." />

Path of assets in CSS files in Symfony 2

Problem
I have a CSS file with some paths in it (for images, fonts, etc.. url(..)).
My path structure is like this:
...
+-src/
| +-MyCompany/
| +-MyBundle/
| +-Resources/
| +-assets/
| +-css/
| +-stylesheets...
+-web/
| +-images/
| +-images...
...
I want to reference my images in the stylesheet.
First Solution
I changed all paths in the CSS file to absolute paths. This is no solution, as the application should (and has to!) be working in a subdirectory, too.
Second Solution
Use Assetic with filter="cssrewrite".
So I changed all my paths in my CSS file to
url("../../../../../../web/images/myimage.png")
to represent the actual path from my resources directory to the /web/images directory. This does not work, since cssrewrite produces the following code:
url("../../Resources/assets/")
which is obviously the wrong path.
After assetic:dump this path is created, which is still wrong:
url("../../../web/images/myimage.png")
The twig code of Assetic:
{% stylesheets
'#MyCompanyMyBundle/Resources/assets/css/*.css'
filter="cssrewrite"
%}
<link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
Current (Third) Solution
Since all CSS files end up in /web/css/stylexyz.css, I changed all paths in the CSS file to be relative:
url("../images/myimage.png")
This (bad) solution works, except in the dev environment:
The CSS path is /app_dev.php/css/stylexyz.css and therefore the image path resulting from this is /app_dev.php/images/myimage.png, which results in a NotFoundHttpException.
Is there a better and working solution?
I have came across the very-very-same problem.
In short:
Willing to have original CSS in an "internal" dir (Resources/assets/css/a.css)
Willing to have the images in the "public" dir (Resources/public/images/devil.png)
Willing that twig takes that CSS, recompiles it into web/css/a.css and make it point the image in /web/bundles/mynicebundle/images/devil.png
I have made a test with ALL possible (sane) combinations of the following:
#notation, relative notation
Parse with cssrewrite, without it
CSS image background vs direct <img> tag src= to the very same image than CSS
CSS parsed with assetic and also without parsing with assetic direct output
And all this multiplied by trying a "public dir" (as Resources/public/css) with the CSS and a "private" directory (as Resources/assets/css).
This gave me a total of 14 combinations on the same twig, and this route was launched from
"/app_dev.php/"
"/app.php/"
and "/"
thus giving 14 x 3 = 42 tests.
Additionally, all this has been tested working in a subdirectory, so there is no way to fool by giving absolute URLs because they would simply not work.
The tests were two unnamed images and then divs named from 'a' to 'f' for the CSS built FROM the public folder and named 'g to 'l' for the ones built from the internal path.
I observed the following:
Only 3 of the 14 tests were shown adequately on the three URLs. And NONE was from the "internal" folder (Resources/assets). It was a pre-requisite to have the spare CSS PUBLIC and then build with assetic FROM there.
These are the results:
Result launched with /app_dev.php/
Result launched with /app.php/
Result launched with /
So... ONLY
- The second image
- Div B
- Div C
are the allowed syntaxes.
Here there is the TWIG code:
<html>
<head>
{% stylesheets 'bundles/commondirty/css_original/container.css' filter="cssrewrite" %}
<link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
{# First Row: ABCDEF #}
<link href="{{ '../bundles/commondirty/css_original/a.css' }}" rel="stylesheet" type="text/css" />
<link href="{{ asset( 'bundles/commondirty/css_original/b.css' ) }}" rel="stylesheet" type="text/css" />
{% stylesheets 'bundles/commondirty/css_original/c.css' filter="cssrewrite" %}
<link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
{% stylesheets 'bundles/commondirty/css_original/d.css' %}
<link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
{% stylesheets '#CommonDirtyBundle/Resources/public/css_original/e.css' filter="cssrewrite" %}
<link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
{% stylesheets '#CommonDirtyBundle/Resources/public/css_original/f.css' %}
<link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
{# First Row: GHIJKL #}
<link href="{{ '../../src/Common/DirtyBundle/Resources/assets/css/g.css' }}" rel="stylesheet" type="text/css" />
<link href="{{ asset( '../src/Common/DirtyBundle/Resources/assets/css/h.css' ) }}" rel="stylesheet" type="text/css" />
{% stylesheets '../src/Common/DirtyBundle/Resources/assets/css/i.css' filter="cssrewrite" %}
<link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
{% stylesheets '../src/Common/DirtyBundle/Resources/assets/css/j.css' %}
<link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
{% stylesheets '#CommonDirtyBundle/Resources/assets/css/k.css' filter="cssrewrite" %}
<link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
{% stylesheets '#CommonDirtyBundle/Resources/assets/css/l.css' %}
<link href="{{ asset_url }}" rel="stylesheet" type="text/css" />
{% endstylesheets %}
</head>
<body>
<div class="container">
<p>
<img alt="Devil" src="../bundles/commondirty/images/devil.png">
<img alt="Devil" src="{{ asset('bundles/commondirty/images/devil.png') }}">
</p>
<p>
<div class="a">
A
</div>
<div class="b">
B
</div>
<div class="c">
C
</div>
<div class="d">
D
</div>
<div class="e">
E
</div>
<div class="f">
F
</div>
</p>
<p>
<div class="g">
G
</div>
<div class="h">
H
</div>
<div class="i">
I
</div>
<div class="j">
J
</div>
<div class="k">
K
</div>
<div class="l">
L
</div>
</p>
</div>
</body>
</html>
The container.css:
div.container
{
border: 1px solid red;
padding: 0px;
}
div.container img, div.container div
{
border: 1px solid green;
padding: 5px;
margin: 5px;
width: 64px;
height: 64px;
display: inline-block;
vertical-align: top;
}
And a.css, b.css, c.css, etc: all identical, just changing the color and the CSS selector.
.a
{
background: red url('../images/devil.png');
}
The "directories" structure is:
Directories
All this came, because I did not want the individual original files exposed to the public, specially if I wanted to play with "less" filter or "sass" or similar... I did not want my "originals" published, only the compiled one.
But there are good news. If you don't want to have the "spare CSS" in the public directories... install them not with --symlink, but really making a copy. Once "assetic" has built the compound CSS, and you can DELETE the original CSS from the filesystem, and leave the images:
Compilation process
Note I do this for the --env=prod environment.
Just a few final thoughts:
This desired behaviour can be achieved by having the images in "public" directory in Git or Mercurial and the "css" in the "assets" directory. That is, instead of having them in "public" as shown in the directories, imagine a, b, c... residing in the "assets" instead of "public", than have your installer/deployer (probably a Bash script) to put the CSS temporarily inside the "public" dir before assets:install is executed, then assets:install, then assetic:dump, and then automating the removal of CSS from the public directory after assetic:dump has been executed. This would achive EXACTLY the behaviour desired in the question.
Another (unknown if possible) solution would be to explore if "assets:install" can only take "public" as the source or could also take "assets" as a source to publish. That would help when installed with the --symlink option when developing.
Additionally, if we are going to script the removal from the "public" dir, then, the need of storing them in a separate directory ("assets") disappears. They can live inside "public" in our version-control system as there will be dropped upon deploy to the public. This allows also for the --symlink usage.
BUT ANYWAY, CAUTION NOW: As now the originals are not there anymore (rm -Rf), there are only two solutions, not three. The working div "B" does not work anymore as it was an asset() call assuming there was the original asset. Only "C" (the compiled one) will work.
So... there is ONLY a FINAL WINNER: Div "C" allows EXACTLY what it was asked in the topic: To be compiled, respect the path to the images and do not expose the original source to the public.
The winner is C
The cssrewrite filter is not compatible with the #bundle notation for now. So you have two choices:
Reference the CSS files in the web folder (after: console assets:install --symlink web)
{% stylesheets '/bundles/myCompany/css/*." filter="cssrewrite" %}
Use the cssembed filter to embed images in the CSS like this.
{% stylesheets '#MyCompanyMyBundle/Resources/assets/css/*.css' filter="cssembed" %}
I'll post what worked for me, thanks to #xavi-montero.
Put your CSS in your bundle's Resource/public/css directory, and your images in say Resource/public/img.
Change assetic paths to the form 'bundles/mybundle/css/*.css', in your layout.
In config.yml, add rule css_rewrite to assetic:
assetic:
filters:
cssrewrite:
apply_to: "\.css$"
Now install assets and compile with assetic:
$ rm -r app/cache/* # just in case
$ php app/console assets:install --symlink
$ php app/console assetic:dump --env=prod
This is good enough for the development box, and --symlink is useful, so you don't have to reinstall your assets (for example, you add a new image) when you enter through app_dev.php.
For the production server, I just removed the '--symlink' option (in my deployment script), and added this command at the end:
$ rm -r web/bundles/*/css web/bundles/*/js # all this is already compiled, we don't need the originals
All is done. With this, you can use paths like this in your .css files: ../img/picture.jpeg
I had the same problem and I just tried using the following as a workaround. Seems to work so far. You can even create a dummy template that just contains references to all those static assets.
{% stylesheets
output='assets/fonts/glyphicons-halflings-regular.ttf'
'bundles/bootstrap/fonts/glyphicons-halflings-regular.ttf'
%}{% endstylesheets %}
Notice the omission of any output which means nothing shows up on the template. When I run assetic:dump the files are copied over to the desired location and the css includes work as expected.
If it can help someone, we have struggled a lot with Assetic, and we are now doing the following in development mode:
Set up like in Dumping Asset Files in the dev Environmen so in config_dev.yml, we have commented:
#assetic:
# use_controller: true
And in routing_dev.yml
#_assetic:
# resource: .
# type: assetic
Specify the URL as absolute from the web root. For example, background-image: url("/bundles/core/dynatree/skins/skin/vline.gif"); Note: our vhost web root is pointing on web/.
No usage of cssrewrite filter
I offen manage css/js plugin with composer which install it under vendor.
I symlink those to the web/bundles directory, that's let composer update bundles as needed.
exemple:
1 - symlink once at all (use command fromweb/bundles/
ln -sf vendor/select2/select2/dist/ select2
2 - use asset where needed, in twig template :
{{ asset('bundles/select2/css/fileinput.css) }}
Regards.

Categories