I often use template->render() to generate HTML snippets. By default they are generated with a full layout. This is something I do not want. My two use cases are AJAX requests where I only need to generate a bit of text, without layout, or HTML pieces that I generate to plug into a PDF library
Usually my code may look like below, where I have to include the boilerplate of 'layout' => false in every such render method call:
This is undesirable to me - it clutters up code, and most of my code does not use the layout facility. How can I make Expressive assume by default that the layout is false, and to specify it explicitly when I need it?
What is the most direct and Expressive-compatible way of doing this?
For clarify, using the above example, I want the end result to be like so, where layout is assumed to be false, unless stated otherwise:
We have middleware to do something very similar. Inject the renderer into it and in the process method check to see if the request is an XHR*. If it is, set your layout = false param.
Add the middleware early in your pipeline and you’re good to go.
not in front of my computer and can’t exactly remember the header to check.
I am aware that this is a very old topic. However, I recently ran into this same issue and since several of the solutions that I found to this problem did not work I thought I would post a working solution for the current version of Mezzio. There are probably better solutions, but this one works.
mezzio v3.17.0
mezzio-viewrenderer v2.12
In a piped Middleware (Mine is piped before DispatchMiddleware, just so there is no question):
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
{
if (! $request->hasHeader('X-Requested-With')) {
// if we do not have this bail early
return $handler->handle($request);
}
if (in_array('XMLHttpRequest', $request->getHeader('X-Requested-With'), true)) {
$this->template->addDefaultParam(
TemplateRendererInterface::TEMPLATE_ALL,
'layout',
false
);
}
return $handler->handle($request);
}
For Ajax requests, it is recommended to use JSON View Model instead of the standard View model. You can see in this link how to register an alternate strategy. For disabling a layout on a particular view, you can use the setTerminal method with a false parameter like below. Thanks!
SomeController extends AbstractAction
public function someAction(){
//your logic
return (new ViewModel($variablesArray))->setTerminal(true);
}
}
True, however, if you are trying to detect async request that are sent via an unknown number of javascript libraries I do not see a way around having the check for X-Requested-With. Nearly all of them that I have ever used send that field with ajax request. I do see what you mean in regards to the Accept field