Twig global variable into symfony controller - symfony

In my Symfony 4 application I use a Twig global variable to store the name of my website. I need to fetch its value both into my templates and controllers.
twig:
globals:
site_title: My blog
I am able to get it inside my Twig templates : {{ site_title }}
In my controller, I tried $this->getParameter('site_title') but :
The parameter "site_title" must be defined.

Try this:
$twigglobals = $this->get("twig")->getGlobals();
and you can get content by:
$site_title = $twigglobals["site_title"];

Related

Passing Twig variables to Vue.js in Symfony

I am running Symfony 4 app with Vue.js enabled. Is there any good practice to send my data from Twig templates to Vue.js components? Currently I have a number of data items for example on my header component, and HTML element data section looks like this:
<header-nav class="headnav headnav-fixed z-depth-1"
logo="{{ asset('build/images/site_logo.png') }}"
username="{{ app.user.name }}"
logout-url="{{ path('logout') }}"
logout-title="{% trans %} Logout {% endtrans %}"
instruction-url="{{ path('system_instruction_download') }}"
instruction-title="{% trans %} Download instruction {% endtrans %}"
current-locale="{{ app.request.getLocale()|upper }}"
v-bind:locales="{{ locales|json_encode }}"
>
Let's say I have a number of different URL's and other stuff. What is the best way to send the data? Should I first prepare an array of URL's on my controller? Which controller should it be if I want to prepare some global variables which will be used on my header, so they shouldn't be locked only on one controller.
Assuming that you render multiple "vue applications", you can define global variables with
1) twig configuration
Documentation says:
"Twig allows to inject automatically one or more variables into all templates.
These global variables are defined in the twig.globals option inside the main Twig configuration file"
2) You could create abstract controller with function merging variables
// MyAbstractController.php
protected function getTwigVariables(array $vars) {
$globals = [];
// ... fill $globals with your stuff
return array_merge(['globalVar1' => ], $vars);
}
// TestController extends MyAbstractController
public function indexAction() {
//...
return $this->render('viewPath.html.twig', $this->getTwigVariables([
'specificVariable' => 'variableContent'
]));
}
You could also embed controllers inside your main twig.
You can create headerAction, footerAction etc. and create subrequest for this actions.
For storing variables you can also use script tags
// twig
<script id="serverJson" type="application/json">{{ jsonContent|json_encode()|raw }}</script>
// serverJson.js
const configElement = document.getElementById("serverJson");
export default JSON.parse(configElement.innerHTML);
// ViewTemplate.vue
import serverJson from "path-to-serverJson.js"

How to use multiple translation files without domains in Twig in Symfony2?

In the Symfony2 project, I'm working on, the translations are files in multiple domain files like
foo.en_GB.xlf
bar.en_GB.xlf
buz.en_GB.xlf
...
foo.de_DE.xlf
bar.de_DE.xlf
buz.de_DE.xlf
...
foo.fr_FR.xlf
...
So in the Twig files I have to define the domain, e.g.:
{% trans from 'my_domain' %}my_key{% endtrans %}
Actually I don't need the domains in this project. All the translations are part of one big domain. So, I want (1) to use multiple translation files and (2) in the same time not to care about the domain, so that
{% trans %}my_key{% endtrans %}
should work for the my_key translated in any /.../translations/*.xlf file.
How to use multiple translation files without domains in a Twig template in Symfony2?
This can be achieved by creating a custom loader without break nothing, all you need is to use a different file extension:
namespace AppBundle\Translation\Loader;
use Symfony\Component\Translation\Loader\XliffFileLoader;
class FooFileLoader extends XliffFileLoader
{
/**
* {#inheritdoc}
*/
public function load($resource, $locale, $domain = 'messages')
{
// ignoring $domain var and pass 'messages' instead
return parent::load($resource, $locale, 'messages');
}
}
Register the translation loader:
services:
app.translation.loader.foo:
class: AppBundle\Translation\Loader\FooFileLoader
tags:
- { name: 'translation.loader', alias: 'foo' }
Later, you must name all your files to:
bar.en_GB.foo
baz.en_GB.foo
bar.de_DE.foo
baz.de_DE.foo
...
All your translation files with .foo extension will be merged and included into messages domain.
You can set the translation domain for an entire Twig template with a single tag:
{% trans_default_domain 'app' %}

SonataAdminBundle dump template variable

I tried dump variables in block template (block_core_children_pages.html.twig) by {{ dump() }} but it turn into blank page. Anybody have same problem? and I have some questions also:
How to pass a variable from function: {{ sonata_page_render_container('footer', 'global' ) }} to template ?
What are variables is passed by default to block template?
Thanksss alot.
The sonata_page_render_container function takes the following arguments:
public function renderContainer($name, $page = null, array $options = array())
So you have the third argument to specify some options/settings to add to your block, like this:
{{ sonata_page_render_container('footer', 'global', {mysetting: myvalue}) }}
After that, you can modify your execute() BlockService's method to use the settings you passed.

Using repository class methods inside twig

In a Symfony2.1 project, how to call custom entity functions inside template? To elaborate, think the following scenario; there are two entities with Many-To-Many relation: User and Category.
Doctrine2 have generated such methods:
$user->getCategories();
$category->getUsers();
Therefore, I can use these in twig such as:
{% for category in categories %}
<h2>{{ category.name }}</h2>
{% for user in category.users %}
{{ user.name }}
{% endfor %}
{% endfor %}
But how can I get users with custom functions? For example, I want to list users with some options and sorted by date like this:
{% for user in category.verifiedUsersSortedByDate %}
I wrote custom function for this inside UserRepository.php class and tried to add it into Category.php class to make it work. However I got the following error:
An exception has been thrown during the rendering of
a template ("Warning: Missing argument 1 for
Doctrine\ORM\EntityRepository::__construct(),
It's much cleaner to retrieve your verifiedUsersSortedByDate within the controller directly and then pass it to your template.
//...
$verifiedUsersSortedByDate = $this->getYourManager()->getVerifiedUsersSortedByDate();
return $this->render(
'Xxx:xxx.xxx.html.twig',
array('verifiedUsersSortedByDate' => $verifiedUsersSortedByDate)
);
You should be very carefull not to do extra work in your entities. As quoted in the doc, "An entity is a basic class that holds the data". Keep the work in your entities as basic as possible and apply all the "logic" within the entityManagers.
If you don't want get lost in your code, it's best to follow this kind of format, in order (from Entity to Template)
1 - Entity. (Holds the data)
2 - Entity Repositories. (Retrieve data from database, queries, etc...)
3 - Entity Managers (Perform crucial operations where you can use some functions from your repositories as well as other services.....All the logic is in here! So that's how we can judge if an application id good or not)
4 - Controller(takes request, return responses by most of the time rendering a template)
5 - Template (render only!)
You need to get the users inside your controller via repository
$em = $this->getDoctrine()->getEntityManager();
$verifiedusers = $em->getRepository('MYBundle:User')->getVerifiedUsers();
return array(
'verifiedusers' => $verifiedusers,
);
}

How to get current bundle in Symfony 2?

How can I detect in which bundle am I?
for exemple, when I'm in web.com/participants/list, I want to read "participants".
In order to get the bundle name in the controller:
// Display "AcmeHelloBundle"
echo $this->getRequest()->attributes->get('_template')->get('bundle');
And inside a Twig template:
{{ app.request.get('_template').get('bundle') }}
In order to get the controller name in the controller:
// Display "Default"
echo $this->getRequest()->attributes->get('_template')->get('controller');
And inside a Twig template:
{{ app.request.get('_template').get('controller') }}
In order to get the action name in the controller:
// Displays "index"
echo $this->getRequest()->attributes->get('_template')->get('name');
And inside a Twig template:
{{ app.request.get('_template').get('name') }}
AFAIK it's not yet possible (at least in a easy way). You should use reflection. I wrote a quick and dirty service to do get bundle name ang guess entity/repository/form names based on my conventions. Can be buggy, take a look at: http://pastebin.com/BzeXAduH
It works only when you pass a class that inherits from Controller (Symfony2). Usage:
entity_management_guesser:
class: Acme\HelloBundle\Service\EntityManagementGuesser
In your controller:
$guesser = $this->get('entity_management_guesser')->inizialize($this);
$bundleName = $guesser->getBundleName(); // Acme/HelloBundle
$bundleShort = $guesser->getBundleShortName(); // AcmeHelloBundle
Another possibility would be using kernel to get all bundles: Get a bundle name from an entity
Well you can get the controller of the current route by,
$request->attributes->get('_controller');
You can parse the bundle name from it.
You can get the bundle name in the controller simply like that:
// Display "SybioCoreBundle"
echo $this->getRequest()->attributes->get('_template')->get('bundle');
And inside a Twig template:
{{ app.request.get('_template').get('bundle') }}

Resources