TYPO3: f:link.action view helper ignores controller property - typo3

Using the following template code, the controller property gets ignored:
<f:link.action
pageUid="{f:cObject(typoscriptObjectPath: 'lib.nav.pid.registration')}"
controller="StandardRegistration"
action="oneClickRegistration"
additionalParams="{tx_extension_standardregistration: '{occurrenceId: conductingEvent.id}'}">
<f:translate key="registration.label.register"/>
</f:link.action>
Instead of calling the action oneClickRegistration, the page gets processed as if no controller property has been set.

Instead of using the property additionalParams, I had to use arguments:
<f:link.action
pageUid="{f:cObject(typoscriptObjectPath: 'lib.nav.pid.registration')}"
controller="StandardRegistration"
action="oneClickRegistration"
arguments="{occurrenceId: conductingEvent.id}">
<f:translate key="registration.label.register"/>
</f:link.action>
The documentaiton for the additionalParams property says:
Additional query parameters that won't be prefixed like $arguments (overrule $arguments).
So it seems not only arguments gets overruled, but also the property controller.

Related

Correct Syntax of Element binding in XML view with JSON model

Trying to get right syntax for context binding in XML view. I have a JSON model and set the model to view with name "company" inside controller. When I use absolute path, it works but when I use relative path, it doesn't. It seems, view is unable to access the model in second case.
My Code
<Text text ="{company>/data/name}" width="200px"/>
<Input binding="{company>/data}" value ="{name}" width="200px"/>
When binding a property, you also have to provide the name of the model. Otherwise the "nameless" default model is assumed. But since all your data is in the company model you have to explicitly state that name for your value.
<Input binding="{company>/data}" value="{company>name}" width="200px"/>

Passing argument from one plugin to another

I have one extension that has 2 plugins. I would to pass an argument from plugin1 to plugin2.
In plugin1's view I generate a link to a page where a content element for plugin2 is inserted:
<f:link.action controller="ApplicationController" action="showFormAction" arguments="{test: 1}" pageUid="40">Link</f:link.action>
In ApplicationController I try to retrieve the test parameter like this:
$this->request->getArgument('test');
But I get this error:
#1176558158: An argument "test" does not exist for this request.
Is there a way to solve or debug this ?
You simply forgot to set pluginName="Plugin2Name" in your f:link.action viewhelper call. You can see that the link currently contains the desired argument but with the namespace of the 1st plugin. If you add pluginName, the namespace will be changed to the 2nd plugin.

Where does the value of $Form come from, when using a standard SilverStripe template?

The Page Layout template for the "simple" theme (the default) contains:
<% include SideBar %>
<div class="content-container unit size3of4 lastUnit">
<article>
<h1>$Title</h1>
<div class="content">$Content</div>
</article>
$Form
$CommentsForm
</div>
Where does the value of $Form come from? ie to make use of it, what do I need to do?
Is it intended that I define a function Form() within the page controller that returns the form?
Yeah, it's a bit of an oddity. $Form is used by the Security controller, which is invoked in login situations (/Security/login, /Security/lostpassword, etc..) and because those templates can be themed, it assumes that you have a $Form variable somewhere in your template that indicates where the form should render.
You only need it in your Page.ss template, as the Security controller just renders a generic Page.
Anything in Silverstripe that extends ViewableData basically doubles as a ViewModel. This includes DataObject and Controller. So things that are publicly accessible on these objects are exposed to the View layer and callable as template variables (be they properties or methods).
Where does the value of $Form come from? ie to make use of it, what do I need to do?
So basically yes, your assumption is correct. If you define public function Form() (which returns a Form instance) in the page controller class you want the form to show on, it will render a form on the template (for all pages of that type).
Is it intended that I define a function Form() within the page controller that returns the form?
What UncleCheese intends to say in his answer is that the variable name $Form is arbitrary. Your method could for instance be named ContactForm(), in which case you'd need to give the template $ContactForm to show the form (be sure that the second parameter to Form constructor reflects this too - http://docs.silverstripe.org/en/3.1/developer_guides/forms/introduction/ using - __FUNCTION__ is a great way to avoid this gotcha).
Form() however does not appear as a function by default in page.php, nor in ContentController, etc. The Security controller however uses Page.ss to render (when you have the CMS module installed) - thus meaning if you do not have $Form in Page.ss somewhere, you will never be able to log in. So it's important to keep this unless you also define a Security.ss to make the login/lostpassword/etc. pages different to the normal Page.ss layout (in which case that template needs $Form).

Using ViewHelper inside a partial path

I'm working on a new extension and my model has the attribute 'type' which can get different strings from the TCA form. Strings only!
The name of the partial that my template should load is inside the 'type' attribute from my model. So here comes my problem. Since TYPO3 4.7.x the .html file names for fluid have to start with an uppercase letter. Inside the 'type' attribute the name of the partial that should be loaded is always lowercase. For that, I wrote a simple view helper that contains only this method:
public function render($string) {
return ucfirst($string);
}
Inside my template I tried to use this view helper for the path to the partial:
{namespace vh=Tx_MyExtension_ViewHelpers}
<f:for each="{obj.subObjects}" as="sub">
<f:render partial="OtherObject/{vh:String.UpperFirstCharacter(string:'{sub.type}')}" arguments="{sub:sub}" />
</f:for>
If I try to load this in the fontend, nothing from my extension will be rendered and there are no error messages anywhere. The problem depends on my view helper, 'cause even if I try to load only this:
{vh:String.UpperFirstCharacter(string:'test')}
{vh:String.UpperFirstCharacter(string:'{sub.type}')}
There is nothing comming back. If I only output {sub.type} it shows me the string that I want, but in lowercase.
Obviously your problem is that you're ViewHelper doesn't do what you want it to do.
First of all, ViewHelper names are to be written in lowerCamelCase.
Second, you don't need to place sub.type in curly braces:
This syntax...
{vh:string.upperFirstCharacter(string:sub.type)}
... should be sufficient.
Fluid will then look for a ViewHelper named
Tx_MyExtension_ViewHelpers_String_UpperFirstCharacter
or namespaced
\My\Extension\ViewHelpers\String\UpperFirstCharacter
Please check that this is the case.
So I found the issue. Fluid can't handle namespaces. So first my ViewHelper looked like this:
<php
namespace TYPO3\MyExtension\ViewHelpers\String;
class UpperFirstCharacterViewHelper ...
Now I changed the name of my class and removed the namespace:
<php
class Tx_MyExtension_ViewHelpers_String_UpperFirstCharacterViewHelper ...
This is how it works. At the moment I work with TYPO3 6.1.6.
Thank you anyway lorenz for your help!
EDIT:
I went fully retarded! Fluid CAN handle namespaces. I just had to set the namespace the right way.
That's how you set the namespace inside the template:
{namespace vh=TYPO3\MyExtension\ViewHelpers}
On top of this comment you can see how my ViewHelper looks like with a namespace.

Zend Framework's Action helper doesn't use a ViewRenderer

I'm trying to execute an action from the view using the Action helper like but although the action is been executed the output isn't displayed.
Here's part of my .phtml file:
<div id="active-users">
<?php echo $this->action('active', 'Users') ?>
</div>
The action works like this:
class UsersController extends Zend_Controller_Action
{
function activeAction()
{
$model = new UsersModel();
$this->view->users = $model->getActiveUsers();
}
}
And there's another .phtml file that renders the list of users. The action works fine when called directly from /users/active but doesn't display anything when called from inside another .phtml file.
I've tracked the problem to the ViewRenderer not been available when called with action() helper... or at least not working as usual (automatically rendering the default .phtml file).
The content is displayed if I explicitly render the view inside the action but I need the ViewRender behaviour because I don't control the code of some of the actions I need to use.
Is there anyway to turn the ViewRenderer on while using the action() view helper? I'm open to replace the action() view helper if needed.
I forgot: I'm using PHP 5.2.8, Zend Framework 1.7.5, Apache 2.2 on Windows Vista.
Thanks
i think you should asign the active users from the controller or if you want you can use singleton on the models an use the directly in the views
$this->view = UsersModel::instance()->getActiveUsers();
Are you using _forward() o redirect on your action? Actions that result in a _forward() or redirect are considered invalid, and will return an empty string.
Update: I test it, and it works, try writing 'users' instead of 'Users' in the controllers param.
<div id="active-users">
<?php echo $this->action('active', 'users') ?>
</div>