When I want to use my custom view helpers in the Twig template while implementing in the ZF2 based project, I need to add the magic method __invoke method in the view helper; otherwise, Twig template engine throw an error which says about unable to call the __invoke method of the view helper.
Now I want to know why I need to declare this __invoke magic function in the view helpers?
Check the docs: https://framework.zend.com/manual/2.1/en/modules/zend.view.helpers.advanced-usage.html
If you want your helper to be capable of being invoked as if it were a method call of the PhpRenderer, you should also implement an __invoke() method within your helper.
The same must apply with the twig renderer, it's trying to execute the helper class (using invoke as a shortcut)
You can see where the PHPRenderer is using __invoke() as a proxy / shortcut to the helpers:
https://github.com/zendframework/zend-view/blob/master/src/Renderer/PhpRenderer.php#L389
/**
* Overloading: proxy to helpers
*
* Proxies to the attached plugin manager to retrieve, return, and potentially
* execute helpers.
*
* * If the helper does not define __invoke, it will be returned
* * If the helper does define __invoke, it will be called as a functor
*
* #param string $method
* #param array $argv
* #return mixed
*/
public function __call($method, $argv)
{
$plugin = $this->plugin($method);
if (is_callable($plugin)) {
return call_user_func_array($plugin, $argv);
}
return $plugin;
}
I imagine the Twig renderer is just doing something similar, infact we can see below it is:
https://github.com/ZF-Commons/ZfcTwig/blob/master/src/ZfcTwig/View/TwigRenderer.php#L83
Related
Having a Grails 2.1 application, where I have a taglibrary for rendering a summary for different controllers, I have an issue pointing at the correct view-folder.
Eg. TestAController and TestBController both have a controller specific view file called summary.gsp in their respective view folders. That is /testa/summary.gsp and /testb/summary.gsp.
How can I my taglib render the summary.gsp that is related to the controller currently in action - I need to set a path like "??/summary-gsp".
I don't want to implement any if/else logic as there could potentially be 10000 controllers using this taglib, all specifying their own summary.gsp.
Is this doable?
You can access the params object in your taglib so:
out << render(template: "/${params.controller}/summary")
The caller should pass in the path to the template as an argument to the tag. If this argument is omitted you could use a convention for locating the template, e.g.
class MyTagLib {
def renderSummary = {attrs ->
def defaultTemplatePath = "/${params.controller}/summary"
def templatePath = attrs.template ?: defaultTemplatePath
out << g.render(template: templatePath)
}
}
I am building an application using Play for Model and Controller, but using backbone.js, and client side templating. Now, I want the html templates to be served by Play without any backing controller. I know I could put my templates in the public directory, but I would like to use Play's templating engine for putting in the strings in my template from the message file. I do not need any other data, and hence dont want the pain of creating a dummy controller for each template. Can I do this with Play?
You could create a single controller and pass in the template name as a parameter, but I am not sure if it is a good idea.
public static void controller(String templateName) {
// add whatever logic is needed here
renderTemplate("Controller/"+templateName+".html");
}
Then point all your routes to that controller method. Forget about reverse routing, though.
I think I would still rather have a separate controller method for each template. Remember that you can use the #Before annotation (see Play Framework documentation) to have the message string handling in exactly one place, that is executed before each controller method. By using the #With annotation you can even have this logic in a separate class.
You can use template engine from any place in your code:
String result = TemplateLoader.load("Folder/template.html").render(data);
I want to do something like this
[MyAttribute(Message="Please upgrade to view " + name)]
public ActionResult Details(string name)
{
....
}
I know I can call filterContext.ActionDescriptor.GetParameters() from inside the attribute code itself, but is there any way to use them in the controller?
The correct way to achieve this is to use a custom action filter and inside use either filterContext.ActionDescriptor.GetParameters() or fetch the required parameter from RouteData. You cannot have dynamic values in an attribute declaration because attributes represent metadata that are baked into the assembly at compile time => .NET doesn't allow you this. Only static or constant parameters could be used at attribute declaration.
I need to create a drop down menu in struts2 from List. How can I create an action class so that when a .jsp page is loaded, it populates the list first?
i found this link http://www.mkyong.com/struts2/struts-2-sselect-drop-down-box-example/ , it works too but for it work user must go to http://localhost:8080/Struts2Example/selectAction.action to make it work but what if someone were to directly go to select.jsp.
Since you're using a .jsp, you could load the dropdown with a scriptlet before you render the <s:select> tag.
However, it's better practice to allow the action to perform the loading and hide the .jsp files under /WEB-INF so they're not directly accessible. A common approach to perform this is the Prepare interceptor.
If you've got it in your interceptor stack, it will automatically invoke any method with the following name in your action before invoking the requested method:
prepare{MethodName}()
prepareDo{MethodName}()
prepare()
That means you can do something like the following in your Action:
public class YourAction extends ActionSupport {
public String prepare(){
// populate your drop down object
}
public String view(){
// forward to your jsp
return SUCCESS;
}
}
Then all you have to do is call your action's view() method and prepare will be called first by Struts.
I want to define my own taglib that will use the g:datePicker to generate some of it's output.
class MyTagLib
def myTag = {attrs ->
// I need to invoke the `datePicker` tag of the the `FormTagLib` tag library
// provided by Grails
}
}
I want to pass along the attributes map when I invoke this tag. When I invoke g:datePicker I would like it to write it's output directly to the response (just as it does when you invoke it within a GSP).
How can I do this?
Thanks.
out << g.datePicker(etc...) ought to do it. The other taglib prefixes are metaprogrammed in automatically.
If you want to add a body, you need to pass a closure:
out<<g.link(action: x, {"This is a link to x"})
or out<<g.link(action: x) {"This is a link to x"}