Symfony 2 custom themes folder - symfony

I'm designing a multi-tenant application with Symfony2, There will be common templates and each tenant could have custom templates. I would like create a theme folder like this(like wordpress with css,img,etc...) :
Themes/commons/base.twig.html
Themes/commons/css/styles.css
Themes/commons/js/script.js
Themes/tenantID/base.twig.html
Themes/tenantID/css/styles.css
Themes/tenantID/js/script.js
Perhaps I'm taking a wrong way...?
Any suggestion ?
Thanks.

There is nothing wrong with your design. I may name "commons" as "default" but thats up to you. Approach with tenantid looks good to me. Whats your question?

https://github.com/fabpot/Twig/issues/17 - no dynamic inheritance
LiipThemeBundle might be a solution: http://symfony2bundles.org/liip/LiipThemeBundle

You can achieve all this by following symfony standard . because if you follow structure you will make full stack full site in frame work and you can also learn how to use frame work.
like in
bundle folder:
userbulndle/css
userbulndle/js
adminbundle/css etc
and use theme forming
{% block gender_widget %}
{% spaceless %}
{% if expanded %}
{% for child in form %}
<div class="radio_ele">
{{form_widget(child) }}
{{form_label(child) }}
</div>
{% endfor %}
{% else %}
{{ block('choice_widget') }}
{% endif %}
{% endspaceless %}
{% endblock %}
{# ----------------------------------------------------------- #}
{% block field_errors %}
{% spaceless %}
{% if errors|length > 0 %}
<div class="error_list">
{% for error in errors %}
{{ error.messageTemplate|trans(error.messageParameters, 'validators') }}
{% endfor %}
</div>
{% endif %}
{% endspaceless %}
{% endblock field_errors %

Related

Reuseable blocks inside of custom form themes in symfony

I want to call a custom block inside an overwritten theme-block:
{% block file_widget %}
{% if image is not null %}
{{ block('imagePreview') }}
{% endif %}
{{ block('form_widget') }}
{% endblock %}
{% block imagePreview %}
<img src="{{ image.getFullPath | imagine_filter('medium_square') }}"
alt="{{ image.filename }}"/>
{% endblock %}
The imagePreview is not shown.
But it is working when I don't use a block.
And it is also working when I dont use a FormTypeExtension and create an ImageType instead.
So I guess the file_widgetblock still has the scope of the parent form_div_layout.html.twig and there in fact no imagePreview block exists.
So how can I solve this.
I mean now I solved it by removing the block.
But I just want to know if someone has a solution to this.
Maybe there is a way for using reuseable blocks inside of custom form themes in symfony?
Finally I found the solution:
I just did not 'use' the base template explicit.
The form theme worked without this - because symfony falls back the the base form theme when it does not find a block inside the new theme file.
But it seems then you also can not use custom blocks inside this new theme file.
So this works now:
{% use 'form_div_layout.html.twig' %}
{% block file_widget %}
{% if image is not null %}
{{ block('imagePreview') }}
{% endif %}
{{ block('form_widget') }}
{% endblock %}
{% block imagePreview %}
<img src="{{ image.getFullPath | imagine_filter('medium_square') }}"
alt="{{ image.filename }}"/>
{% endblock %}

Twig Runtime Error: Impossible to invoke a method ("test") on a string variable

I have the following twig template (the code is in the same file):
{% macro renderJob(fields) %}
// renders the job UI block, but I've removed it for simplicity
Hello world.
{% endmacro %}
{% block _jobs_widget %}
<div id="jobsContainer">
{% for fields in form.children %}
{% dump fields %}
{{ _self.renderJob(fields) }}
{% endfor %}
</div>
{% endblock %}
For some reason, after upgrading to twig/twig = v2.1.0 I'm receiving the follwing error:
Impossible to invoke a method ("renderJob") on a string variable ("#AppBundle/Jobs/form/job.html.twig").
I have been trying to figure out what's causing this without any luck. This used to work just fine in 1.3.x. The fields variable contains the proper data, but it appears it can't pass it to the renderJob macro or it can't find the macro (which is kind of odd)?
Have you tried the following ?
{% import _self as renderJobMacro %}
{% macro renderJob(fields) %}
// renders the job UI block, but I've removed it for simplicity
Hello world.
{% endmacro %}
{% block _jobs_widget %}
<div id="jobsContainer">
{% for fields in form.children %}
{{ renderJobMacro.renderJob(fields) }}
{% endfor %}
</div>
{% endblock %}
I think _self is depricated from twigg 2.0, May be you need to check without _self.
Check {{ renderJob(fields) }} instead of {{ _self.renderJob(fields) }}

Overwriting a field of AdmingeneratorGeneratorBundle

I am trying to overwrite a field of the AdmingeneratorGeneratorBundle and want to append a link to a certain field. That works quite well following the documentation:
{% extends_admingenerated "MyMainBundle:PageEdit:index.html.twig" %}
{% block form_status %}
{{ parent() }}
Preview
{% endblock %}
What I would need to do now, is to get the real id of my page instead of the static 8, but i could not figure out, what the object is called inside the twig template. Any ideas?
Update:
In my case, as I only need the ID of my page, I can use app.request.attributes.get('pk') to get it in twig. Would be interesting how to get other values tough.
Just use
{% extends_admingenerated "MyMainBundle:PageEdit:index.html.twig" %}
{% block form_status %}
{{ parent() }}
Preview
{% endblock %}
Cedric
The Documentation has been updated.
Thats ho it works:
{% extends_admingenerated "NamespaceYourBundle:List:index.html.twig" %}
{% block list_td_column_title %}
<span style="font-weight:bold">{{ Movie.title }}</span>
{% endblock %}

Control the way form validation errors are displayed in Symfony2

How do I globally change the way form validation errors are displayed in Symfony2? For example, if I want to wrap each one of my error messages in a <span class="error"> or something like that, how would that be done?
Note: I'm aware of this question/answer, but I'm not sure that it's the same question as mine, and I don't understand how to apply the selected answer.
Take a look at the docs: custom global theme, customizing error output
{# SomeBundle:Layout:fields.html.twig #}
{% block field_errors %}
{% spaceless %}
{% if errors|length > 0 %}
<span class="error">
{% for error in errors %}
{{ error.messageTemplate|trans(error.messageParameters, 'validators') }}<br />
{% endfor %}
</span>
{% endif %}
{% endspaceless %}
{% endblock field_errors %}
{# In your form template #}
{% form_theme form 'SomeBundle:Layout:fields.html.twig' %}

How to customize a CollectionType() item?

This ยง of the Symfony2 documentation shows an awesome technique for customizing an individual field. I'm using it a lot but there is one particular Type for which I'm having a hard time doing the customization : the CollectionType() Customizing the collection itself is quite easy, you can do something like this:
{% block _mynamespace_mybundle_mytype_mycollectionfield_row %}
{% if prototype is defined %}
{% set attr = attr|merge({'data-prototype': form_widget(prototype) }) %}
{% endif %}
{% spaceless %}
<ul {{ block('widget_container_attributes') }}>
{% spaceless %}
{{ form_errors(form) }}
{% for child in form %}
<li>
{{form_widget(child)}}
</li>
{% endfor %}
{% endspaceless %}
{{ form_rest(form) }}
</ul>
{% endspaceless %}
{% endblock %}
But how can you customize each element of the collection ? And how can you customize the data-prototype using Twig (the data-prototype is a special attribute used to add new items with js)?
I tried doing something like this (for the data-prototype):
{% block _mynamespace_mybundle_mytype_mycollectionfield_$$name$$_row %}
customization ok!
{% endblock %}
But I get errors, because I don't know how to escape the $
Regarding the items, I tried many things:
{% block _mynamespace_mybundle_mytype_mycollectionfield_item_subfield_row %}
customization ok!
{% endblock %}
{% block _mynamespace_mybundle_mytype_mycollectionfield_element_subfield_row %}
customization ok!
{% endblock %}
None of them work.
I asked the question in symfony's bug tracker, and it seems there is no solution, but a good workaround is creating a custom type for each subfield you want to customize. See this issue

Resources