Symfony2 getting the url of request in subrequests in twig - php

How can I get the current url in a subrequest and change parameters with it(for example locale).
I have main action that renders the template.
public function indexAction() {
return $this->render('MpShopBundle:Frontend:index.html.twig', array(
'products'=>$products,
'locale' => $locale,
));
}
In the template I render the navigation like this:
<span class="top">{% render controller("MpShopBundle:Navbar:navbar") %}</span>
Now in this navbar template I am trying to do this:
{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge({'_locale': 'en'})) }}
I am getting an empty url because this is a subrequest... How can I pass the URL to the subrequest? This is the first time im dealing with them..

Related

OctoberCMS global page properties?

Is it possible to set a series of global properties (such as social media usernames) that are available to all page views in OctoberCMS rather than having them associated to one CMS page or Static Page at a time?
For example, being able to use {{ twitter_username }} in any template, but it wouldn't show up as a field in any page form on the backend.
UPDATE: this can be achieved by registering a Twig function using registerMarkupTags in your plugin:
use System\Classes\PluginBase;
class Plugin extends PluginBase
{
public function registerMarkupTags()
{
return [
'functions' => [
'globals' => function($var) {
switch ($var) {
case 'twitter_username':
return 'mytwitterusername';
}
return null;
},
],
];
}
}
In this case, calling {{ globals('twitter_username') }} from any template prints mytwitterusername.
Hmm yes better you need to add code to life-cycle method in layouts, so now page which are using that layout will have this info already loaded.
In layout code block you can use something like this
use RainLab\Pages\Classes\Page as StaticPage;
function onStart() {
$pageName = 'static-test'; // this will be static page name/filename/title
$staticPage = StaticPage::load($this->controller->getTheme(), $pageName);
$this['my_title'] = $staticPage->viewBag['title'];
$this['twitter_username'] = $staticPage->viewBag['twitter_username'];
}
now inside your cms page you can use this variable
<h1>{{ my_title }} </h1>
<h3>{{ twitter_username }} </h3>
let me know if it you find any issues
You could also use theme config file which gives you more flexibility rather than hardcoding the values in to the code block.
https://octobercms.com/docs/themes/development#customization

Symfony CMF menu translation

I try to set up a simple CMS on our web application using the Symfony CMF.
I can successfully load the fixtures in multiple languages.
$parent = $dm->find(null, '/cms/pages');
$rootPage = new Page(array('add_locale_pattern' => true));
$rootPage->setTitle('main');
$rootPage->setParentDocument($parent);
$rootPage->setName('main');
$rootPage->setBody('');
$dm->persist($rootPage);
$aboutPage = new Page(array('add_locale_pattern' => true));
$aboutPage->setTitle('About');
$aboutPage->setParentDocument($rootPage);
$aboutPage->setBody('About us DE');
$aboutPage->setName('about');
$aboutPage->setLabel('About');
$dm->persist($aboutPage);
$dm->bindTranslation($aboutPage, 'de');
$aboutPage->setBody('About us FR');
$aboutPage->setLabel('About FR');
$dm->bindTranslation($aboutPage, 'fr');
I can also display them in the right language (current locale) on the front page.
This is my controller action:
public function pageAction(Request $request, $contentDocument) {
return $this->render(':Frontend/CMS:index.html.twig', ['page' => $contentDocument]);
}
And this is my working twig File:
{{ page.body }}
Screenshot of the working page
But as soon as I try to render a menu on my page, it will show the text in the default language.
{{ knp_menu_render('main') }}
{{ page.body }}
Screenshot of the non working page
The menu is configured as follow:
cmf_menu:
persistence:
phpcr:
menu_basepath: /cms/pages
The output of app.request.locale is always fr. No matter if I include the menu or not.
Does anyone have an idea what could cause this problem?

Laravel - Breadcrumbs module : pass array of arguments

I am using this module .
I defined my Breadcrumbs, and now I'm trying to render in my blade template by doing the following :
{!! Breadcrumbs::render($breadcrumbs) !!}
The value of $breadcrumbs being "controlled" by my controller.
The problem is that I would like to be able to pass an array of arguments to this render() method, and not only simple strings. Indeed, here are some Breadcrumbs I declared :
Breadcrumbs::register('home', function($breadcrumbs)
{
$breadcrumbs->push('Home', route('home'));
});
/* .... etc .... */
Breadcrumbs::register('style', function($breadcrumbs, $style_name, $style_slug)
{
$breadcrumbs->parent('styles');
$breadcrumbs->push($style_name, route('style', $style_slug));
});
In this situation, I need to be able to pass an array of arguments to the render() method, which will be sent by the Controller to the View.
I tried the following :
{!! call_user_func_array(Breadcrumbs::render, $breadcrumbs) !!}}
But I get the following error :
Undefined class constant 'render'
This module has a renderArray() method. Next time, I'll read the documentation till the end :)

How to get value of passed parameter in controller by Block in magento?

I have passes value from controller like
{{block type="test/test" name="test123" catstatus="xyz" template="storelocator/abc.phtml" }}
i am trying to get value of catstatus on abc.phtml page by
$this->getData('catstatus');
i am able to get this on the phtml page
but I am not getting blankstring when get this value on my indexcontroller.php
Please suggest a possible solution.
Please refer below code
//Loading current layout
$this->loadLayout();
//Creating a new block
$block = $this->getLayout()->createBlock(
'Mage_Core_Block_Template',
'test_block_name',
array('template' => 'page/html/testblock.phtml')
);
$this->getLayout()->getBlock('content')->append($block);
//Now showing it with rendering of layout
$this->renderLayout();

Symfony2 form: How to render the same element twice in the same view

I have a controller where I am creating a form witg two dropdown list inside.
When I am rendering my view, I would like to have the same form elements on the top and the bottom of the page. The problem is that the form elemetns (dropdownlists) are displayed only on the top of the page, even if I am asking twig to put them also on the bottom.
Here is what I would like to have:
The 1 and 2 are the dropdownlists. And I would like to duplicate this on the top and on the bottom of the page.
Any Idea on how can this be done?
The top content and the bottom content, where the two dropdownlists are inside are in a single sseparate twig file (searchPanel.html.twig) and this file is included in the page
{% include "MyBundle:Search:searchPanel.html.twig" %}
Here is the searchPanel.html.twig
<div class="searchPanel">
<form action="{{ path }}" method="POST" {{ form_enctype(form) }}>
Papers per page
{{ form_widget(form.papers_per_page, { 'class': 'ppp'}) }}
/ Sort by
{{ form_widget(form.sort_by, { 'class': 'sort'}) }}
{{ form_rest(form) }}
/ Papers ({{ papers_number }} results)
<input type="submit" class="updateSearchResults" value="Update"></input>
</form>
A problem in your approach is that Symfony's Form-component will render the form elements with id's which would be duplicated if you rendered the same form twice on your page. You might also run in trouble with the csrf_token. The gist being that forms are not intended to be duplicated.
Here is what I would do. Create a twig-template containing your paginator form without using Symfony\Form, i.e. create all form elements statically and pass it the paginator-object (or array) to get the data instead of using form_widget(). Something like this:
<form action="{{ path(app.request.attributes.get('_route') }}" method="POST">
<select name="paginator[per_page]">
{% for per_page in paginator.papers_per_page %}
<option value=""{{ per_page }}">{{ per_page }}</option>
{% endfor %}
</select>
</form>
The form action will automatically submit the data to your current route, so you can embed it in different actions and it will submit the data to the same action. On POST you can just create a paginator-object with the post-data and then add it as the form's data. After that you just use isValid() as usual.
In your controller you can get the data like this:
use Symfony\Component\HttpFoundation\Request;
// ...
public function PaperController()
{
public function listAction(Request $request)
{
if ($request->getMethod() == 'POST') {
$data = $request->request->get('paginator');
$paginator = new Paginator($data);
$form = new PaginatorFormType();
$form->setData($paginator);
if ($form->isValid()) {
// ...
}
}
}
}
You can easily embed the form in your view like this:
{{ include 'AcmeDemoBundle:Form:paginator.html.twig' with { 'paginator': paginator } }}
Basically you just use the Form-component in your controller for validation purposes. If you want to set some default values or add additional arguments you might want to create a macro from that template, but for your use case this should suffice. Maybe someone else has a better solution but this is how I went with a similar problem in one of my projects.
another option is user the render twig helper. That way is is possible render the same form in the page as many time as you want. A difference is that using this helper, is also necessary to treat the form renderization as an independent controller Action namely:
in every place in your twig template you want to render the form in the helper to invoke the form there's must be something like this:
{{ render(controller('BundleNameBundle:Controller:Action', {
'param': paramId
})) }}
Thereafter is just a matter of creating the controller...
Another option is in the controller to create 2 forms:
//first form
$form = $this->createForm(new MyFormType(), ...);
//second form: must have different form name that default,
//to render in twig the fields with different ids
$formType = new MyFormType();
$formType->setName('second_form_name');
$formSecond = $this->createForm($formType, ...);
Send both when rendering the twig form:
return $this->render( ...
'form' => $form->createView(), 'formSecond'=>$formSecond->createView()));
Then define the second with name as
formSecond
, and it will conflict with the first.

Categories