Symfony assets relative to bundle - twig

EDIT | http://symfony.com/doc/current/assetic/asset_management.html#assetic-cssrewrite
So does this mean I absolutely have to upload the CSS assets into "web" myself? Is there not a way to use assetic:dump to copy them from the bundle first?
I have an application which is divided multiple smaller application via bundles.
One bundle in particular is an attempt to integrate a legacy app into symfony to run the same platform as a few other apps.
This LegacyBundle has JS and CSS assets which I do not want manually uploaded into "web" - I was under the impression that using assetic allowed me to have the CLI tools compress and re-locate the assets into the web directory.
This seems to be the case using #LegacyBundle prefix on the asset paths:
{% block javascripts %}
{% javascripts
'#LegacyBundle/Resources/legacy/common/extjs/ext-all.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
Problem is - I need this same functionality with CSS files and apparently there is an issue using # shortcut with CSS files and assetic:
http://symfony.com/doc/current/assetic/asset_management.html
Notice that in the original example that included JavaScript files, you referred to the files using a path like #AppBundle/Resources/public/file.js, but that in this example, you referred to the CSS files using their actual, publicly-accessible path: bundles/app/css. You can use either, except that there is a known issue that causes the cssrewrite filter to fail when using the #AppBundle syntax for CSS stylesheets.
So I am trying to avoid using #LegacyBundle syntax for both JS and CSS - however I still wish to reference their paths in twig using the path relative to the bundle - where they go after that is of no concern to me.
What am I missing? Is what I am trying to do possible?
I tried moving ext-alljs.js into the bundle "Resources" root directory and then inside twig template I call the assets via
{% block javascripts %}
{% javascripts
'Resources/ext-all.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
Unfortunately this doesn't work - whereas the previous example does. I am hoping I just have the path incorrect or something?

Related

How to output an uploaded SVG as code in Timber

I'm building a site with Wordpress + Timber and need to output an uploaded SVG image as code.
Here's what I've got, but it's not working:
{% for block in section.blocks %}
<img src="{{ Image(block.icon).src }}"> <!-- this works as exptected -->
{{ function('file_get_contents', Image(block.icon).src) }} <!-- this fails -->
{% endfor %}
The error generated is "failed to open stream", but the URL that Image(block.icon).src provides is a full, valid URL (ie I can go to it in my browser and it loads).
What am I missing? Or is there a better approach?
{{ function('file_get_contents', Image(map.flag).src) }} works for me. Should work for you if you are using advance custom fields in WordPress.
There is two way to load external code in twig file.
Include method :
{% include 'my.svg.twig' %}
Twig source function :
{{ source(my.svg.svg) }}
Also, you can try WP_PLUGIN_DIR constant with file_get_contents + your file url.
{{ function('file_get_contents', 'WP_PLUGIN_DIR'.Image(block.icon).src) }}
PS. Source function works like include.
More info about twig source function is here : https://twig.symfony.com/doc/2.x/functions/source.html

Choose twig block process order

I want to make modular css load with instruction in twig
{{ addCss("csspath") }}
{# rest of template #}
and then write all css in a twig block in my html header like this :
{% block css %}
{{ writeCss() }}
{% endblock %}
My custom function work well, all css store with addCss will be write by writeCss but I have some problem with twig processing order. Css needs to be in head html tag and because of that twig process writeCss before all my addCss call.
I've made some test to guess twig process order by i have no ideo of how control it.

How to push values to array in templates and partials to output them in layout?

We are using Twig as our templating engine but I'm stuck with a problem of the rendering order now. See - https://straightupcraft.com/articles/twig-processing-order
We are using amp for our new site and with amp and web components in general it is necessary to import the components (once) to use them. So the idea was to create a Twig Extension to accomplish exactly this. Everytime a component is used it is called via this twig function call. The function is checking the component, adding it to a stack and you can use it from now on. The stack then is transformed into a list of imports for the head of the page.
The problem here is Twigs top to bottom rendering. When I call said function in a partial or a template the rendering of "layout.twig" already took place and all function calls below/after are not affecting the stack.
Is there an option to change the rendering to inside out, so that the rendering is first using the lowest partial and "bubbles" up to templates and finally layout without them rendering before?
Another way to get the values in layout would nice as well.
Desired behavior:
Layout.twig
{{ getAllComponents() }}
{# should output component1 and component2 #}
{% block content %}
Page.twig
{% extends Layout.twig %}
{{ addComponent('component1') }}
{% include partials.twig %}
<component1>...</component1>
partials.twig
{{ addComponent('component2') }}
<component2>...</component2>
Actual behavior:
Layout.twig
{{ getAllComponents() }}
{# is empty #}
There is no option to change this behavior. However you can use a trick to archive this:
Render your content to a variable before you call getAllComponents()
layout.twig
{% set mainContent %}
{% block content %}{% endblock %}
{% endset %}
{{ getAllComponents() }}
{{ mainContent }}
There actually is a magical solution to this problem -- some genius wrote this Deferred Twig Extension which lets you run some code (output a variable, call a function, etc) in a block near the top of your layout, but wait until the rest of the twig templates have parsed before executing them. There's an example on that github page showing how you can achieve this.
As far as I know, no you cannot switch the rendering of a TWIG template.
However, I would recommend possibly looking at the {% embed %} or {{ render }} tags.
Embed allows specific TWIG files to be placed within others with variables, so you could pass each component into their relevant partials.twig file.
Render allows the use of embedding a separate controller action, so you create a ControllerAction that took in a component variable and renders its own TWIG file.
Documentation on Embed: https://twig.sensiolabs.org/doc/2.x/tags/embed.html
Documentation containing Render: https://twig.sensiolabs.org/doc/2.x/api.html

Patternlab twig includes with params

I am using the node version of patternlab with twig as template engine. I am using twig because my codebase is written in twig - so using mustache it not an option.
I simple try to include an pattern:
<button type="button" class="btn {{ buttonClass }}">{{ cta }}</button>
in an other pattern with:
{% include "base-button" with {'buttonClass': 'btn-primary btn-xs'} %}
This does not work. The pattern is included but the variable buttonClass is not set.
Any Ideas?
This seems to be an issue with the twig integration in this repo https://github.com/pattern-lab/patternengine-node-twig.
There are other issues with twig core features described here: https://github.com/pattern-lab/patternlab-node/issues/554
I finally decided to switch to the php/twig edition and the same twig-patterns are working as expected. If anybody have to use the node edition, i recommend to use mustache.
I believe there are plans to pass the Twig rendering in Pattern Lab Node to PHP, however, this isn't ready yet, but using The Twig engine for Patternlab/Node you can pass a variable via an include. It doesn't work exactly the same as normal twig but it does work.
{% set buttonClass = 'btn-primary btn-xs' %}
{% include "components-button" with buttonClass %}
You can also pass multiple variables:
{% include "components-button" with buttonClass anotherVariable %}

symfony3 override fields theme from vich bundle

I have installed VichUploaderBundle into my Symfony app and would like to have better control of the appearance of the upload buttons. I have taken the contents of fields.html.twig located in the bundle itself, and copied them into the same file at the path app/Resources/views/myControllerName/fields.html.twig This is also where all the other twig templates are for that set of controllers.
I can not seem to affect anything on the page through this method. Yes I have cleared the cache, I have even removed the cache directory.
Am I placing the file in the wrong place?
You can override that form theme in many ways, just when you customize vich_file_widget and/or vich_image_widget e.g.:
{% extends 'base.html.twig' %}
{% form_theme form _self %}
{% block vich_file_widget %}
{# some content… #}
{% endblock %}
{% block content %}
{{ form(my_form) }}
{% endblock %}
Thanks for the effort #jkucharovic, I was already using the 3rd method you were suggesting. My question was whether or not I put the fields.html.twig file in the correct place. Turns out I did not. For others that come along with this question, to override the fields file in the VichUploaderBundle for twig you must put a copy of the fields.html.twig file at the following path so that Symfony can override what comes with the bundle.
the fields file is found here and should not be edited...
vendor/vich/uploader-bundle/Resources/views/Form/fields.html.twig
a copy of that file should be placed here in Symfony 3. This file is editable.
app/Resources/VichUploaderBundle/views/Form/fields.html.twig

Resources