Für die Benutzerfreundlichkeit ist es deutlich besser Eingaben auf der Webseite (z.B. Kommentare) als Ajax Request zu versenden. Mit den richtigen Neos Bordmitteln ist das Ganze auch schnell gemacht
Als erstes benötigen wir einen Controller, der die eigentliche Logik für den Request enthält. Dieser sollte von einem RestController erben. Als View benutzten wir eine JSONView. Diese encodiert die Rückgabewerte automatisch ins JSON-Format.
namespace Vendor\Package\Controller;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\Controller\RestController;
use Neos\Flow\Mvc\View\JsonView;
use Neos\FluidAdaptor\View\StandaloneView;
class ApiController extends RestController //Von RestController erben
{
protected $viewObjectNamePattern = JsonView::class; //View anpassen
protected $resourceArgumentName = 'variablenName'; //Name der übergebenen Variable
/**
* @param array $variablenName
*/
public function createAction(array $variablenName) //Variablenname ist abhängig von $this->resourceArgumentName (s.o.)
{
//Durchführen nötiger Aktionen (z.B.) speichern
//Optional: GGf. gerendertes Template zurück geben
$template = new StandaloneView();
$template->setTemplatePathAndFilename('resources://Vendor.Package/Private/Templates/[...].html');
$template->assign('variable', $variablenName);
$this->view->assign('html', $view->render());
//Ggf. weitere Variablen hinzufügen
$this->view->assign('identifier', 123213);
//Bestimmen, welche Variablen im Antwort-JSON vorkommen sollen
$this->view->setVariablesToRender(['html', 'identifier']);
//Ggf. den Statuscode anpassen
$this->response->setStatus(201);
}
}
Damit wir auch auf die neue Methode zugreifen dürfen, muss die Policy.yaml des Packages noch etwas erweitert werden:
privilegeTargets:
'Neos\Flow\Security\Authorization\Privilege\Method\MethodPrivilege':
'Vendor.Package:ApiController':
matcher: 'method(Vendor\Package\Controller\ApiController->(.*)Action())'
roles:
'Neos.Flow:Everybody':
privileges:
-
privilegeTarget: 'Vendor.Package:ApiController'
permission: GRANT
Um den Controller später über eine URL erreichen zu können, benötigen wir eine neue Route. Diese legen wir folgendermaßen in der Routes.yaml des Packages an. Später können wir diese dann mit dem {f:uri.action()} ViewHelper ermitteln.
-
name: 'Ajax API'
uriPattern: 'api/{@action}'
defaults:
'@package': 'Vendor.Package'
'@controller': 'Api'
'@format': 'json'
Das Formular im Frontend schicken wir jetzt über Ajax an die neu geschaffene Schnittstelle.
<form action="{f:uri.action(action: 'create', controller: 'Api', package: 'Vendor.Package', absolute: true)}" method="post" class="ajax-form">
<input type="text" name="variablenName[email]" placeholder="you@domain.com" />
<input type="text" name="variablenName[name]" placeholder="Max Mustermann" />
<input type="submit" value="Absenden"/>
</form>
$(".ajax-form").submit(function (e) {
e.preventDefault();
var self = this;
$(self).find(':submit').prop('disabled', true);
$.ajax({
type: "POST",
url: $(self).attr('action'),
data: $(self).find(":input").serialize(),
dataType: "json",
success: function (response) {
/*
* Alle an Werte aus $this->view->setVariablesToRender()
* sind in response enthalten
*/
},
error: function (response) {
/*
* Alle an Werte aus $this->view->setVariablesToRender()
* sind in response enthalten
*/
}
});
});