Use files in the public folder within template subfolder in Symfony 5 - symfony

I'm currently using CSS in my Twig templates. The CSS is in my public folder and templates are in the templates folder.
So the following code is working actually :<link rel="stylesheet" href="assets/libs/css/style.css">
Here comes the problem. I created a sub directory in the templates folder but when I try to access to the CSS like before; Symfony don't find my CSS file.
I fixed this issue by using ../ before the href so I have this :<link rel="stylesheet" href="../assets/libs/css/style.css">
My problem is solved at this point but I want something more generic than ../ because if I have some folders inside a folder which is inside the templates folder I would have something like that ../../../ and it's really ugly.
So I am currently looking for a generic way to access to the public folder no matter where I am in the templates folder.
If my question isn't clear enough I know how to do this in Blade with {{ URL::to('/') }} so in Blade my code would have been like that : <link rel="stylesheet" href="{{ URL::to('/') }}/assets/libs/css/style.css">

Symfony has a twig function for what you want as part of the Asset-component. If you use Webpack Encore you will likely already have this installed otherwise you can install it via composer:
composer require asset
This should create a default configuration for you and you should be able to use the following in your templates:
{{ asset('/assets/libs/css/style.css') }}
As the docs for Linking to CSS, JavaScript and Image Assets state:
The asset() function's main purpose is to make your application more portable. If your application lives at the root of your host (e.g. https://example.com), then the rendered path should be /images/logo.png. But if your application lives in a subdirectory (e.g. https://example.com/my_app), each asset path should render with the subdirectory (e.g. /my_app/images/logo.png). The asset() function takes care of this by determining how your application is being used and generating the correct paths accordingly.

Related

How to include CSS in Symfony 5

I am building a Symfony 5 app and want to use CSS inside my twig templates. My stylesheet is at public/css/styles.css and so I try to use it in my twig template with the line <link href="{{ asset('css/styles.css') }}" rel="stylesheet" type="text/css"/>. This works locally but once I deploy it to the Google Cloud Platform the server can no longer find it. The console shows a 404 error when trying to find the stylesheet. Where does Symfony want me to put my css files?
This feels like it should be very simple but I'm totally at a loss and feel like I'm missing something stupid. The documentation only really talks about Encore and that seems like such overkill for using a single CSS file in a twig template.
(sorry i cant comment because low reputations, thatswhy i need to take an answer)
At first, the location of your css is correct. Also the usage of your link tag looks fine. Now the question is: what is the correct error message, or better where looks the browser to your file?
I think the browser want to take your file from root, not from public folder. If you can answer this with yes, you have to check your .htaccess file and/or linking from webspace to startfolder (public) in this cause.
It works in localhost because the symfony dev-server take this work for you.
Got the CSS working. I think what did it was telling app.yaml to put the css in the public folder.
handlers:
- url: /css
static_dir: public/css
Then instead of loading using the asset() function, I included the css with:
<link href="/css/styles.css" rel="stylesheet" type="text/css"/>
That way, the css folder I had in public locally was put in public when deployed to the GCP.

Accessing an image in CSS after activating assets in Twig and Symfony2

I am trying to create my own template with Symfony 2, but the problem is with the CSS when I write backround:url('images/img.png') the image doesn't show, but in my base.html.twig this URL works very well "{{ asset('images/templatemo_ads.jpg ') }}".
I have put my CSS and images folders into web folder because I will use them in other bundles and I use this command to activate assets PHP app/console assets:install web.
background:url() is conflict the default function of url() in the symfony/asset bundle.
Try inline js:
$('.test').css("background", "url({{ asset('images/templatemo_ads.jpg ') }}) no-repeat");
You should use "./" or "../" at the start of the CSS url.
When you use it, it says to the file system to look into the file system from the CSS file, when you don't you are setting a path to add after the current URL to look for the file there (associated with symfony routing, it might work on the homepage if it's the naked domain name, but that's it.)
You should avoid using JS on file sourcing, since people might block it.

Specify alternative fallback paths for Symfony to find twig templates for bundles

Basic Question
How can you make symfony look in non-standard directories to find the "best" (custom) Twig template to load for a bundle view?
The Symfony docs say by default it looks in two locations to override a Twig template
When the AcmeBlogBundle:Blog:index.html.twig is rendered, Symfony
actually looks in two different locations for the template:
app/Resources/AcmeBlogBundle/views/Blog/index.html.twig
src/Acme/BlogBundle/Resources/views/Blog/index.html.twig
But this is discussing how you would override a vendor bundle. In my case, I have native bundles in my /src/ that I want to overwrite on a per Design Template or Client specific basis. It needs to look in:
Client: /var/www/vhosts/{ID}/src
Template: /var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src
Twig Loader has a convenient method to add paths:
$templatePath = '/var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/Resources/views';
$this->container->get('twig.loader')->prependPath($templatePath, 'template');
This allows me to register an alternative path to the template resources, so that I can render the template shell like this:
{% extends '#template/shell/shell.html.twig' %}
But what about when I want to overwrite a bundle template, e.g.
Original: /var/www/core/cms/src/Gutensite/MenuBundle/Resources/views/Menu.html.twig
Custom: /var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src/Gutensite/MenuBundle/Resources/views/Menu.html.twig
How do I register a generic /src/ file so that Symfony looks in there for all references to Vendor Bundle paths, e.g. trying to render #GutensiteMenu/Menu.html.twig will first look in the custom directory for 1) Client , 2) Template, 3) default bundle directory by that name.
Need Assets
Because my TemplateBundle/Templates/Admin/Resources/ are in a non-standard location, assetic won't dump them to the public directory (or create symlinks)... so I'm not sure how to dynamically make assetic find these files.
I'm also not sure how to load the assets that are in these other locations, e.g. this doesn't work:
{% stylesheets '#GutensiteTemplateBundle/Templates/Admin/Resources/public/css/site.css' %}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}
Presumably because it's not dumped.
Why do I need this?
I am building a hosted CMS that is a core vendor which contain various bundles with controllers and templates, e.g. /Gutensite/CmsBundle, Gutensite/ArticleBundle.
Based on the selected "Design Template" for a site, a design template is referenced in a TemplateBundle, e.g. /TemplateBundle/Templates/Admin (a template called "Admin"). The TemplateBundle need to be able to override the core controllers or views.
I have registered the Gutensite/TemplateBundle/Templates/Admin/src/ folder as an alternative namespace for the Composer app/autoload.php, so that controllers can be overwritten as long as they have the same Gutensite namespace (and this works great):
// in my primary controller:
$loader = $GLOBALS['loader'];
$loader->add('Gutensite', '/var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src', true);
NOTE: I could register every single template as a bundle, and that would theoretically allow me to override controllers and bundles using symfony's built in methods. But this would add a lot of "bundles" that aren't really traditional bundles. Also I need the above solution to point to alternative template paths, because I also need the ability to point to client's custom files located outside the normal symfony root directory (which I successfully do with the namespace auto loader paths for controllers).
You can use the path option in the twig configuration, with the same namespace for 2 paths.
twig:
# ...
paths:
"%kernel.root_dir%/../src/Gutensite/MenuBundle/Resources/views": templates
"%kernel.root_dir%/../src/Gutensite/TemplateBundle/Templates/Admin/src/Gutensite/MenuBundle/Resources/views": templates
Then, using #templates/Menu.html.twig will first look for Menu.html.twig in MenuBundle, then in TemplateBundle.
That's this way that the TwigExtension is registering paths so the loader is looking in app/Resources/views and then in the bundle's views.

How to make Assetic scan Twig templates outside bundle

TLDR: How do I make Assetic scan for assets in Twig templates outside bundle?
I've got few registration wizards. Each of these wizards has it's own view directory, the file structure looks like this:
/SiteBundle/Wizard/General/Resources/views
/SiteBundle/Wizard/CountrySpecific/Resources/views
/SiteBundle/Wizard/[...several more...]/Resources/views
In config.yml I defined these paths for twig so I can use #general_wizard/template.html.twig paths:
twig:
paths:
"%kernel.root_dir%/../src/MyWeb/SiteBundle/Wizard/General/Resources/views": general_wizard
"%kernel.root_dir%/../src/MyWeb/SiteBundle/Wizard/CountrySpecific/Resources/views": country_specific_wizard
The problem is that assets used in these templates (inside the Wizard directories) are not dumped using assetic:dump. When I move the view sources to regular SiteBundle/Resources/views, then all the assets are correctly dumped.
Is there a way to make Assetic check the external templates too?
It is not possible with the stock assetic:dump (SF 2.3), as the /Resources/views/ path is hardcoded in the GeneratorBundle, which again provides the list of files to process to assetic. Of course, you could write your own command, but you would basically reinvent the wheel.
I would recommend to keep with the Resources/views convention, and create the subcategories below that:
/SiteBundle/Resources/views/General
/SiteBundle/Resources/views/CountrySpecific
That would have the same effect, and would not require you to write your own commands and mess around with SF2 internals.
I encountered the same problem after moving all templates to templates in the project root, as it will probably come to be in future versions of Symfony.
The simplest solution is to configure all assets in the configuration file and to locate the output files in the web directory, e.g., all bootstrap CSS files into web/css/bootstrap.css. A remaining difficulty is that referencing the assets with the javascripts tag doesn't work anymore because those tags have to be scanned by the Assetic Bundle to work. You have to do this the old-fashioned way, e.g., via {{ asset('css/bootstrap.js') }}.
With Bootstrap I encountered difficulties to make Glyphicons work, since the cssrewrite filter doesn't work as before. I went for Fontawesome at that point, but including your own copy of Glyphicons could also work.

Django external css file problem

For a couple of days now I have been trying to setup my django project to run my html-template with an external css-file. So far, no succes....
I have installed staticfiles ( Im using django 1.2.4.) and put the 'staticfiles' in INSTALLED_APPS within settings.py and added the following code:
STATIC_ROOT=os.path.join(os.path.abspath(os.path.dirname(file)), "static")
STATIC_URL='/static/'
My css-file is located under /static/css/stylesheet.css
My html-template has the link
link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/stylesheet"
After running the server, the page loads just fine. However django cant find my stylesheet...
What am I doing wrong here?
The static root and url doesn't actually host the files. The static serve option (in the urls.py) mentioned previously is a good option for development and learning, but if you move to a deployment server you should use the static hosting provided by your webserver.
The way the static folders is intended to work is that you add the path locations for each app, project, etc to the static directories setting in settings.py. Then, when you run the command "django-admin.py collectstatic" django pulls all of your directories into your static root. After the first time you run collectstatic, only files that have changed will be copied again. This consolidates multiple static directories into one common place.
Static files documentation
You need to pass the RequestContext to the view, so it will run through the staticfiles' CONTEXT_PROCESSORS (which includes the STATIC_URL variable).
from django.template.context import RequestContext
context = {'my_other_context': 1}
render_to_response('your_template.html',
context_instance=RequestContext(request, context))
I would recommend you to just use a django.views.static.serve instance like this in the url.py file:
(r'^(?P<path>.*)$', 'django.views.static.serve',{'document_root': '/path/to/css/'}),

Resources