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.
Related
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>
I have a Symfony2 app that must serve different themes. These themes are essentially directories containing CSS files (eventually other files and minified into a single one).
In Phalcon, I could dynamically set the asset location of my assets in the controller. In Symfony, assets are explicitly defined. My current solution is as follows, but it doesn't look great. This is the HTML of my base.html.twig. I have a property theme in my entity and I define the theme object in my controller.
Basically I'm looking for the proper way to do this in Symfony. Otherwise, I'll just do it like this.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
{% if theme is defined %}
{% for asset in theme.css %}
<link rel="stylesheet" href="{{ asset.url }}"/>
{% endfor %}
{% endif %}
</head>
<body>
{% block page %}
Welcome to the default page!
{% endblock %}
{% block javascripts %}
{% if theme is defined %}
{% for asset in theme.js %}
<script src="{{ asset.url }}"></script>
{% endfor %}
{% endif %}
{% endblock %}
</body>
</html>
I think the most elegant way is to define a default theme, and put the diffrent themes into a root folder, just like this:
themes/
default/
css|js|images...
blue/
css|js|images...
yellow/
css|js|images...
then in Twig template engine, you can use it like this way:
<link rel="stylesheet" href="themes/{{ theme_name|default("default") }}/css/app.css"/>
<script src="themes/{{ theme_name|default("default") }}/js/app.js">
I would like to generate a pdf from an html.twig template but something wrong...
In fact, the PDF has been create with the good content but there is no layout. It's seems the CSS files are not import...
I use Bootstrap from twitter to manage the layout.
Here the part of my controller
$filename = "CI-TRI-".$Chrono->getChrono();
$this->get('knp_snappy.pdf')->generateFromHtml(
$this->renderView('WebStoreMainBundle:Admin:customInvoiceTemplate.html.twig', array('User'=>$User,'Parts'=>$parts, 'device'=>$device, 'rate'=>$rate)),
__DIR__.'/../../../../web/download/'.$filename.'.pdf'
);
And here my layout :
<html>
<head>
{% block stylesheets %}
<link rel="stylesheet" type="text/css" href="{{ asset('bootstrap/css/bootstrap.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset('bootstrap/css/customInvoice.css') }}">
<base href="http://{{app.request.host}}">
<meta charset="UTF-8" >
{% endblock %}
</head>
<body>
{% block header %}
<div class="span2">
<img src="{{ asset('bootstrap/img/GTO_logo.png') }}">
</div>
{% endblock %}
{% block content %}
{% endblock %}
</body>
Wish someone can help me..
PS: Sorry for the typos, english is not my native language.
It would be easier to supply absolute parameter like that:
<link rel="stylesheet" type="text/css" href="{{ asset('bootstrap/css/bootstrap.css', absolute=true) }}">
The assets must be linked using absolute paths. So instead of:
<link rel="stylesheet" type="text/css" href="{{ asset('bootstrap/css/bootstrap.css') }}">
It should be:
<link rel="stylesheet" type="text/css" href="http://yourdomain.com/bootstrap/css/bootstrap.css">
I had this issue myself and this sorted it out for me.
Take note when using Symfony 2.7, Twig has removed absolute argument for asset() function.
<link rel="stylesheet" type="text/css" href="{{ absolute_url(asset('bootstrap/css/bootstrap.css')) }}">
See New in Symfony 2.7: the new Asset component for more info.
#user1805558's answer worked for me. I was also using Less, and used this, which some may find helpful to see:
{% block stylesheets %}
{% stylesheets filter='lessphp' combine=true output='css/pdf.css.twig'
'../app/Resources/assets/css/pdf.less'
%}
<link rel="stylesheet" type="text/css" href="{{ asset(asset_url, absolute=true) }}"/>
{% endstylesheets %}
{% endblock %}
UP for absolute option in asset call :
<img src="{{ asset('/assets/img/AVNZ-Logo-H-SMALL.jpg', absolute=true) }}">
It's related in official bundle repo :
https://github.com/KnpLabs/KnpSnappyBundle/issues/78
I had the same problem. As commented in this issue your asset URLs need to be absolute.
This can be accomplished in symfony using the asset twig funtion and "package urls":
http://symfony.com/doc/current/reference/configuration/framework.html#assets-base-urls
For example:
<link rel="stylesheet" type="text/css" href="{{ asset('bootstrap/css/bootstrap.css') }}">
And then, in your app/config/config.yml
framework:
# ...
templating:
assets_base_urls:
http:
- "http://yourdomain.com/"
If you are in your local configuration, inside your config_dev.yml you should use a different URL instead, like:
- "http://localhost/myproject/web/"
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
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="..." />