Call ViewHelper from Controller - php

i`m trying to call a ViewHelper Function from within a Controller in Typo3 (to add some additional header data)
Base is the Yag Gallery.
I edited the ItemListController.php and added the following:
$pager = $this->extListContext->getPagerCollection();
$prevLinkUid = $pager->getPreviousPage();
$arg = Tx_YAG_ViewHelpers_Namespace_GPArrayViewHelper::render([page:$prevLinkUid], $pager)
$test = '<link rel="test" href="' . $arg . '">';
$this->response->addAdditionalHeaderData($test);
The addAdditionalHeaderData function works well with other data (e.g. $prevLinkUid, so this part is functioning well).
If i understand the syntax of GPArrayViewHelper::render correctly, i need a pageUid as first argument and the pagerCollection as second argument (derived from this call within Resources/Private/Partials/Pager/Default.html
<extlist:link.action controller="{controller}" action="{action}" arguments="{extlist:namespace.GPArray(object:'{pagerCollection}' arguments:'page:{pager.previousPage}')}"><span><</span> </extlist:link.action>
)
However - if i try this Controller my page won't render, so i assume there is something wrong with the php code / function call, maybe even the syntax of the key value pair/first argument? Sorry, i'm not a professional in php
Any ideas how can i achieve this? I read that it may be difficult to use ViewHelpers from within other controllers?

there is a ViewHelperInvoker class which you can use to render a viewhelper in a controller:
$viewHelperInvoker = GeneralUtility::makeInstance(\TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperInvoker::class);
$result = $viewHelperInvoker->invoke(
\TYPO3\CMS\Fluid\ViewHelpers\Format\CurrencyViewHelper::class,
[ 'currencySign' => '€' ],
new \TYPO3\CMS\Fluid\Core\Rendering\RenderingContext(),
function() {
return 12345.67;
}
);
https://github.com/TYPO3/Fluid/blob/master/src/Core/ViewHelper/ViewHelperInvoker.php

Viewhelpers are not supposed to be used outside of Fluid templates.
However, there might be an easier way to achieve what you want, e.g. with HeaderAssets. This way you can easily add snippets to the <head> of your page from within a controller action or page template.

Please really don't to that. What you can do is using the PageRenderer. E.g. using
$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
$pageRenderer->addHeaderData($headerData);

Related

Laravel : form does not change the URL after submit, causing me to be unable to do another POST in web.php

I have a bit of a complicated issue. I could use some help.
I have a form that is being handled by the following function:
$module = request('module');
$classe = request('classe');
$horaire = request('horaire');
$date = request('date');
$students = DB::select('SELECT * FROM `etudiants` WHERE etudiants.id_classe = '.$classe);
return view('g_absence.absence',['module'=> $module, 'classe'=>$classe,'horaire'=>$horaire,'date'=>$date,'students'=>$students]);
I take the values $module, $class, $horaire, $date and $students and need to use them inside a different view: g_absence.absence. This works fine and when the view is returned I have access to said variables.
The issue is, inside the g_absence.absence view, I have another form that also needs to be handled, and because the url remains the same even tho a different view is returned, I cant make two posts for the same path.
web.php:
Route::get('/testboy', [App\Http\Controllers\g_absence::class,'index'])->name('marquer');
Route::post('/testboy',[App\Http\Controllers\g_absence::class, 'marquer']);
Route::post('/testboy',[App\Http\Controllers\g_absence::class, 'ajoutabsence']);
The first line is the one that send to the form page just a simple
return view
The second one handle the form in that view
The third one, I want it to handle the form inside the
g_absence.absence view, but they share the same path.
Excuse me if I'm being unclear, I'm a bit of a beginner in Laravel
your problem is using the same route for different methods
basically the first route gets executed every time you use the '/testboy' action that is why your second function never get's called.
you can solve this issue by changing your urls for example:
Route::post('/testboy-marquer',[App\Http\Controllers\g_absence::class, 'marquer']);
Route::post('/testboy-ajoutabsence',[App\Http\Controllers\g_absence::class, 'ajoutabsence']);
Or you can use one function that's handle both with one url by pathing additional parameter to your url depending on your function call :
Route::post('/testboy?type=marquer',[App\Http\Controllers\g_absence::class, 'ajoutabsence']);
in your function check the type :
if(request('type') == 'marquer') {
execute marquer logic here...
} else {
execute absence logic here...
}
Using method and path with two functionalities is wrong, but if you want to somehow use both routes my same method and path which I don't recommend you must let the request to pass through like a middleware in your first block of code Instead of return a view.
Recommended way is to have 2 routes with different paths or at least one route with a parameter by which you can determine what code block must be executed.

Laravel equivalent or alternative for CodeIgniter

I am trying to figure out how to do the equivalent of the following in Laravel that I would do in CodeIgniter all the time to build views:
$section = $this->load->view('pages/about', $data, TRUE);
This would allow me to echo $section in another view file and then when that view was called the normal way, it would render it. I am not sure how to do something like this in Laravel.
UPDATE
I figured it out. What I was needing was Laravel's HtmlString class to take a string and convert it to html markup to the view file.
You would need to use the View Facade, so make sure to include it with an "Use" statement in your Controller, but basically is this:
$html = View::make('pages/about', $data)->render();
The render() method will just render the view in HTML, instead of returning it as a Response object like the view() helper function does.
There are several ways to do so, try this:
return view('admin.profile', $data);
Read through this doc:
https://laravel.com/docs/5.5/views

Mustache send the data to php function?

I'm having different languages on my web application.
Now i would like to do write: About us in the mustache file.
but then depending on the language the user has chosen (logic in the view/controller), it should display the correct translation for About us.
The translation would be something i have stored for exactly the words: About us
I have seen another webapplication that does it this way:
{{#lang}}About us{{/lang}}
But I dont understand how this is working? How can the lang() method in the view model grab the data within #lang, "About us" - and then replace it with something else, if exists.
(the procedure grabbing the translation from database or file, that matches "About us" do i not need to know)
I didn't know it is possible to reverse like that, sending the "About us" to the lang() method in view model?
Hope someone can explain and with example. Thanks
This is what I tried, in my view:
public function lang($input)
{
return "test" . $input;
}
But this does not work. (No argument passed to lang() )
I am using Mustache (Kostache) together with PHP in a MVC framework (kohana)
Assuming you have mustache defined as $m the following would add the function lang when the template was being parsed.
The key here is passing the function to mustache when rendering.
$data = new StdClass;
$data->lang = function($text) {
return "Requested lang: $text";
}
$m.render($template, $data);
This template
{{#lang}}About us{{/lang}}
Would become
Requested lang: About us
After alot of headache, very bad google results, here is the correct solution if you use Kostache 2 and Kohana 3.2/3.0 :
SIMPLY, in the Kohana_Kostache class at the factory() method where Mustache_Engine intializes, you add a helper function:
'helpers' => array(
'i18n' => function($text) {
return __($text);
}),
Since I use the Kohana Translation system, I called it i18n and it returns __($text), which is the $text translated if exists.

Multiple action contexts in Zend

I am new to Zend and am working on a project that requires three contexts for a particular action. There is the standard context that will normally be used, an AJAX context for AJAX calls, and finally a print-friendly context. The goal is for each of these to have their own view, so the view files used would be something like:
/action_name.phtml
/action_name.ajax.phtml
/action_name.print.phtml
I read http://framework.zend.com/manual/en/zend.controller.actionhelpers.html and came up with:
public function init()
{
// add any necessary context switching here
$contextSwitch = $this->_helper->getHelper('AjaxContext');
$contextSwitch->addActionContext('history', 'html')
->initContext();
//need to add another context for the print view
$this->_helper->getHelper('contextSwitch')->addActionContext('history','print')->initContext();
}
The first two lines I am convinced works, but I am not sure if I am going about the print context the right way, since in the examples the second parameter is normally a file type, like JSON, XML, HTML, etc. Am I going about things the right way or is there something else I should be doing?
It's everything in the documentation. If you want custom contexts, you have to add them first:
$this->_helper
->getHelper('contextSwitch')
->addContext('print', array(
// context options go here
))
->addActionContext('history', 'print')
// more addActionContext()s goes here
->initContext();
What you might do instead of using a context for the print view is just have a parameter in the URL like /print/1. Then in the controller action, check to see if that parameter is true, and if it is, render the "print" view script instead of the regular view script.

Is this acceptable to be placed in a view?

Kohana (and probably other frameworks) allow you get a route and echo its URL, creating routes that are easy to maintain.
Contact
Is this OK to have in the view, or should I assign it to a variable, and then pass the view the variable?
Thanks
You aren't performing logic here. This is perfectly acceptable.
Of course your view code would be a bit cleaner if you created a variable in your controller, but this really is fine IMHO.
I find such a concatenation unnecessary. It seems url::base() going to be used in every link on the site. Why not to have a method to add it automatically? Something like Route::url("contact")
And usage of such a construct in the template is OK.
You can create a function or static method for generating urls:
public static function url($routename, array $params = NULL)
{
return url::base().Route::get($routename)->uri($params);
}

Categories