Formularbeispiel
Live-Demo öffnen unter /documentation/examples/run/forms.
Dieses Beispiel zeigt benannte, serverseitig gerenderte Formulare im DotApp PHP Framework. Die Live-Seite ist reines HTML, sendet per POST an dieselbe URL und lädt dotapp.js nicht.
Einführung
Drei Formulare können denselben POST-Endpunkt nutzen, wenn jedes Formular ein Token {{ formName(Name) }} enthält. Der Controller ruft für jeden erwarteten Formularnamen $request->form(['POST'], 'Name', $ok, $err) auf und gibt die gerenderte Seite für das passende Formular zurück.
Wenn Sie neu bei DotApp sind, lesen Sie zuerst die Grundlagen zu Modulen und Routing:
Das Examples-Modul erstellen
Erstellen Sie das Modul Examples mit der DotApper CLI:
php dotapper.php --create-module=Examples
Das Live-Modul wird nur für die URLs des Beispiel-Runners aktiv. Halten Sie den Routenumfang in /app/modules/Examples/module.init.php explizit:
public function initializeRoutes()
{
return ['/documentation/examples/run', '/documentation/examples/run/*'];
}
Den Forms-Controller erstellen
Erstellen Sie einen Controller namens Forms für das Modul Examples:
php dotapper.php --module=Examples --create-controller=Forms
Controller in DotApp 2.0 stellen öffentliche statische Aktionsmethoden bereit und werden über Modul-Controller-Zeichenketten wie 'Examples:Forms@index!' referenziert.
Routen konfigurieren
Definieren Sie ein Routenpaar für die URL mit und ohne Schrägstrich. Das Live-Modul verwendet einen kleinen Helfer, damit GET und POST konsistent bleiben:
public function initialize($dotApp)
{
Config::module('Examples', 'prefix') ?? Config::module('Examples', 'prefix', '/documentation/examples/run');
$p = rtrim((string) Config::module('Examples', 'prefix'), '/');
$pair = function (string $path): array {
$path = rtrim($path, '/');
return [$path, $path . '/'];
};
Router::get($pair($p . '/forms'), 'Examples:Forms@index!', Router::STATIC_ROUTE);
Router::post($pair($p . '/forms'), 'Examples:Forms@submit!', Router::STATIC_ROUTE);
}
Die GET-Aktion rendert die Formularseite. Die POST-Aktion prüft den übermittelten Formularnamen und gibt eine neue HTML-Antwort zurück.
Die View erstellen
Die Live-Demo verwendet eine eigenständige View unter /app/modules/Examples/views/forms.view.php. Die Datei ist ein vollständiges HTML-Dokument.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{{ var: $title }} - DotApp PHP Framework 2.0</title>
<link rel="stylesheet" href="/assets/modules/Examples/css/examples.css" />
</head>
<body class="ex-body">
<main class="ex-main">
<h1>Named forms</h1>
<p>Three forms post to the same URL. This demo does not use dotapp.js.</p>
{{ if $formNumber }}
<div class="ex-status">Using form {{ var: $formNumber }}, you submitted the text: {{ var: $formText }}</div>
{{ /if }}
<form method="POST">
<input type="text" name="textfrom1" placeholder="Enter text to display" />
{{ formName(Form1) }}
<button type="submit">{{ var: $btnName }}</button>
</form>
<form method="POST">
<input type="text" name="textfromanother" placeholder="Enter text to display" />
{{ formName(Form2) }}
<button type="submit">{{ var: $btnName }}</button>
</form>
<form method="POST">
<input type="text" name="textfromanother" placeholder="Enter text to display" />
{{ formName(Form3) }}
<button type="submit">{{ var: $btnName }}</button>
</form>
</main>
</body>
</html>
Die Tags {{ formName(Form1) }}, {{ formName(Form2) }} und {{ formName(Form3) }} müssen innerhalb der zugehörigen <form>-Tags stehen.
Formulare verarbeiten
Der Live-Controller gibt die HTML-Zeichenkette zurück. Jeder Aufruf von $request->form() enthält sowohl einen Erfolgs- als auch einen Fehler-Callback, sodass nicht passende Formularprüfungen sicher fortgesetzt werden können.
use Dotsystems\App\Parts\Logger;
use Dotsystems\App\Parts\Renderer;
use Dotsystems\App\Parts\Response;
class Forms extends \Dotsystems\App\Parts\Controller
{
public static function index($request)
{
return self::formPage('', 0);
}
public static function submit($request)
{
$attempts = [
1 => ['Form1', 'textfrom1'],
2 => ['Form2', 'textfromanother'],
3 => ['Form3', 'textfromanother'],
];
foreach ($attempts as $num => $spec) {
$html = $request->form(['POST'], $spec[0], function ($request) use ($num, $spec) {
$text = (string) ($request->data()[$spec[1]] ?? '');
return self::formPage($text, $num);
}, function () {
return null;
});
if (is_string($html) && $html !== '') {
return $html;
}
}
return self::formPage('', 0);
}
private static function formPage(string $text, int $formNumber)
{
return self::view('forms', [
'title' => 'Named forms demo',
'docsUrl' => '/documentation/examples/forms',
'btnName' => 'Send',
'formNumber' => $formNumber,
'formText' => htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'),
]);
}
private static function view(string $name, array $vars)
{
$r = Renderer::new()->module('Examples')->setView($name, 'clean');
foreach ($vars as $key => $value) {
$r->setViewVar($key, $value);
}
$html = $r->renderView();
if ($html === '') {
Logger::use()->error('Examples view empty', ['view' => $name]);
return new Response(500, 'Template error');
}
return $html;
}
}
Renderer::new()->module('Examples')->setView('forms', 'clean') wählt die eigenständige View aus, bevor Variablen mit setViewVar() zugewiesen werden.
Rendering-Theorie
DotApp kann eine vollständige View direkt rendern oder eine View, die {{ content }} und ein Layout enthält. Dieses Live-Beispiel verwendet den direkten Ansatz mit eigenständiger View, weil die Demoseite in sich abgeschlossen ist.
$r = Renderer::new()->module('Examples')->setView('forms', 'clean');
$r->setViewVar('btnName', 'Send');
$html = $r->renderView();
Layout-Rendering kommt zum Einsatz, wenn ein gemeinsamer Wrapper nützlich ist. Diese Anleitung verwendet die eigenständige Seite forms.view.php.
Live-Demo
Probieren Sie die Live-Demo unter /documentation/examples/run/forms. Sie sendet drei benannte Formulare an einen Endpunkt und gibt die gerenderte Seite aus dem Controller zurück.