How to fetch value from url in silverstripe - silverstripe

I want to print value 5 on the ss page.
www.xyz.com?a=5.
How to fetch url data in silverstripe? Any help is accepeted.

In your controller that your Silverstripe template is for, you can retrieve "GET" (aka. query string) by returning the result of $this->getRequest()->getVar('a') in a function on your controller.
It is good practice to use $this->getRequest()->getVar('a') over $_GET['a'] as SilverStripe will automatically sanitise the string.
When your code is not in the controller (so you can't make use of $this->getRequest()), you can request the current controller by using Controller::curr() which will make the complete call for getting a single var:
Controller::curr()->getRequest()->getVar('a')
If you want to get all "GET" variables, just call getVars() instead..
Also, you can access "POST" variables in a similar calling postVar('a') or postVars() instead. If you want to get the value from both "POST" or "GET", you can call requestVar('a') or requestVars().
Anyway, here is a basic mock-up of a controller using a function on the controller that is accessible in the template.
Controller
class TestPage_Controller extends Page_Controller
{
public function init()
{
parent::init();
}
public function MySpecialProperty()
{
return $this->getRequest()->getVar('a');
}
}
Template
<p> $MySpecialProperty </p>

Related

Is it possible to request the controller without retuning thymleaf model

Hello I use Thymealf and want to do a validirung against my database before I subbmitte.
When I call the controller I get the error:
Error resolving template [], template might not exist or might not be accessible by any of the configured Template Resolvers
I think the error comes from the fact that I don't returne a modal.
Is there a way to make a request without thymleaf ?
Controller
#GetMapping("/getByKey/{key}")
public KeyValuePair keyExists(#PathVariable("key") String key){
return ssdbService.getByKey(key);
}
or do I understand here something completely wrong ?
Use a #RestController instead of a #Controller if you want to return data.
You can also just annotate your method with #ResponseBody if you just want one method to return data instead of the entire controller.
#ResponseBody
#GetMapping("/getByKey/{key}")
public KeyValuePair keyExists(#PathVariable("key") String key){
return ssdbService.getByKey(key);
}

Spring mvc: is there a way to call another controller, get the response and fill it to a model attribute?

I have two mvc style endpoints returning templatefile names as view names, in the same classpath: /source and /target. The source_template has a variable which needs to be filled by contents of another template, say target_template.
#RestController
class SomeController {
#GetMapping("/source")
public String source(Model model) {
model.addAttribute("attr1", /*call endpoint /target and add the response of parsed template 'target_template' here */);
return "source_template";
}
#GetMapping("/target")
public String target(Model model) {
model.addAttribute("attr2", "good");
//may be continue the nested invocation n number of times
return "target_template";
}
}
given the source_template.html:
Hai, $attr1
and the target_template.html:
this has been a $attr2 day
having said, i invoke the url /source, I should get "Hai, this has been a good day".
I can just call the target() method directly, but that would not render the template. Or I should directly use the templating engine apis to link the template file, put the context object, parse the template and return the string , which defeats the whole purpose of spring mvc. Or I can use resttemplate, but that requires an absolute url, and performance would take a hit. So, is there any other way to do it ?

Override MVC routes where applicable without inheriting controller

Say I have a controller FooController which has a bunch of action methods. Some of these methods would I like to override, but none of the methods are marked as virtual and I do not want to change the code of FooController.
So I implement a CustomFooController (not inheriting from FooController) and write new versions of the methods that I want.
Now I want to route first to CustomFooController and if the action is not available there I want to default to FooController. I have set up this route config to override the route:
routes.MapRoute(
"customFoo",
"foo/{action}",
new { controller = "CustomFoo", action = UrlParameter.Optional }
);
Here is some example definitions:
public class FooController : Controller
{
public ActionResult Bar { ... }
public ActionResult Baz { ... }
}
public class CustomFooController : Controller
{
public ActionResult Bar { ... }
}
So when accessing /Foo/Bar we should hit CustomFooController.Bar() and when accessing /Foo/Baz we should hit FooController.Baz() since Baz() is not implemented in CustomFooController.
But I get "The resource cannot be found", I understand why, but can I somehow work around it without modifying FooController?
You might want to have a look at HandleUnknownAction() (see msdn reference page).
It is invoked when a request matches a controller, but no method with the specified action name is found in that controller.
So you could override that method in your CustomFooController to redirect to the appropriate action in FooController (or even other controllers based on your custom inspection of request related data).
Redirection can be done with RedirectToAction() (see msdn reference page)
I think I found a neat solution myself. Since I don't want to modify FooController and a bunch of other controllers from another application I'm extending (and relying on updates from) I decided to use extension method MapMvcAttributeRoutes() from System.Web.Mvc.RouteCollectionAttributeRoutingExtensions in my startup RouteConfig in order to first match with route attributes on e.g. my CustomFooController which takes precedence over the conventional routing.
Just to be on the safe side: HandleUnknownAction() is implemented only in CustomFooController. You don't have to modify FooController (or other controllers).

How To Call a Common function to Every (Twig) Symfony2

Hi I have a common function to get a Client Name dynamicaly. Now I want to call that function to every view (Twig). I am following it like this:
//My controler
public function getSchoolNameAction(){
$session = new Session();
$dm = $this->getDocumentManager();
$commonFunction = new CommonFunctions();
return $schoolName= $commonFunction->schoolName($dm,$session);
}
//My View (search.html.twig)
{% render controller('EduAccountBundle:Ledger:getSchoolName') %}
But its showing an error that :
he controller must return a response (null given). I need to make it for every view. Please guide me how to fix this
Don't define a controller as a service, controllers should be used only to take a request and to produce a response (you're just returning a value, that isn't acceptable for Symfony logic)
Unless you want to return a rendered template (or produce a valid response, such like a json response) to put where you're calling the common action (you could do that of course), I will recommend to write a custom twig extension

What is the best way to "fake" DELETE and PUT methods using JAX-RS?

I've just started to use Jersey to create a RESTful API for my site. Its a wonderful change from having to roll my own support for RESTful services in Java. One thing I just can't seem to figure out is how to "fake" a DELETE and PUT method.
Jersey supports the annotations #PUT and #DELETE, however many Load-Balancers will not allow these methods through. In the past I've relied on the ability to define a custom HTTP header (e.g. x-method-override: DELETE) and "tunneling" within a POST request.
Has anyone found a way to bind a method using Jersey/JAX-RS annotations to custom headers? Alternatively, is there a better way around lack of support for PUT and DELETE?
Well here is how I've decided to handle the situation within my API. Its relatively simple and doesn't require much additional coding. To illustrate consider a RESTful api for Address:
#Path("/address")
public class AddressService {
#GET
#Produces("application/xml")
public StreamingOutput findAll() { ... }
#POST
#Produces("application/xml")
#Consumes("application/x-www-form-urlencoded")
public StreamingOutput create(...) { ... }
//
// This is the alternative to a "PUT" method used to indicate an "Update"
// action. Notice that the #Path expects "/id/{id}" which allows
// us to bind to "POST" and not get confused with a "Create"
// action (see create() above).
//
#POST
#Produces("application/xml")
#Consumes("application/x-www-form-urlencoded")
#Path("/id/{id}")
public StreamingOutput update(#PathParam("id") Long id, ...) { ... }
//
// This is the typical "GET" method with the addition of a check
// for a custom header "x-method-override" which is designed to
// look for inbound requests that come in as a "GET" but are
// intended as "DELETE". If the methodOverride is set to "DELETE"
// then the *real* delete() method is called (See below)
//
#GET
#Produces("application/xml")
#Path("/id/{id}")
public StreamingOutput retrieve(
#PathParam("id") Long id,
#HeaderParam("x-method-override") String methodOverride)
{
if (methodOverride != null && methodOverride.equalsIgnoreCase("DELETE")) {
this.delete(id);
}
...
}
//
// This is the typical "DELETE" method. The onlything special about it is that
// it may get invoked by the #GET equivalent is the "x-method-override" header
// is configured for "DELETE"
//
#DELETE
#Produces("application/xml")
#Path("/id/{id}")
public StreamingOutput retrieve(#PathParam("id") Long id) { ... }
}
It's not really REST anymore, but in a similar situation we defined POST /collection/ to be insert (as normal), POST /collection/{id} to be update, POST /collection/{id} without body to be delete.

Resources