1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect3 id="zend.controller.actionhelpers.viewrenderer">
<title>ViewRenderer</title>
<sect4 id="zend.controller.actionhelper.viewrenderer.introduction">
<title>Einführung</title>
<para>
Der <emphasis>ViewRenderer</emphasis> Helfer wurde designt um die folgenden Ziele
erfüllen:
</para>
<itemizedlist>
<listitem>
<para>
Entfernen der Notwendigkeit View Objekte innerhalb der Controller zu
instanzieren; View Objekte werden automatisch mit dem Controller registriert.
</para>
</listitem>
<listitem>
<para>
Automatisch View Skript, Helfer und Filter Pfade setzen basierend auf dem
aktuellen Modul, und den aktuellen Modulnamen automatisch als Klassenprefix für
Helfer und Filterklassen assoziieren.
</para>
</listitem>
<listitem>
<para>
Ein global vorhandenes View Objekt für alle bearbeitenden Controller und
Aktionen erstellen.
</para>
</listitem>
<listitem>
<para>
Dem Entwickler erlauben das Standard View Rendering Optionen für alle Controller
gesetzt werden.
</para>
</listitem>
<listitem>
<para>
Die Fähigkeit hinzufügen das ein View Skript ohne Intervention automatisch
gerendert wird.
</para>
</listitem>
<listitem>
<para>
Dem Entwickler erlauben seine eigenen Spezifikationen, für den View Basisnamen
und für View Skriptpfade, zu erstellen.
</para>
</listitem>
</itemizedlist>
<note>
<para>
Wenn man ein <methodname>_forward()</methodname>,
<methodname>redirect()</methodname> oder <methodname>render()</methodname> manuell
durchführt, wird kein automatisches rendern erfolgen, da man beim Ausführen von
jeder dieser Aktionen dem <emphasis>ViewRenderer</emphasis> mitteilt das man seine
eigene Ausgabe durchführen will.
</para>
</note>
<note>
<para>
Der <emphasis>ViewRenderer</emphasis> ist standardmäßig aktiviert. Man kann Ihn
über den Parameter <emphasis>noViewRenderer</emphasis> des Frontcontrollers
deaktivieren (<command>$front->setParam('noViewRenderer', true);</command>)
oder den Helfer vom Helfer Broker Stack entfernen
(<methodname>Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')</methodname>).
</para>
<para>
Wenn man Einstellungen vom <emphasis>ViewRenderer</emphasis> vor der Ausführung des
Front Controllers ändern will, kann das auf zwei Wegen getan werden:
</para>
<itemizedlist>
<listitem>
<para>
Instanzieren und Registrieren eines eigenen
<emphasis>ViewRenderer</emphasis> Objekts und dieses an den Helfer Broker
übergeben:
</para>
<programlisting language="php"><![CDATA[
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer();
$viewRenderer->setView($view)
->setViewSuffix('php');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
]]></programlisting>
</listitem>
<listitem>
<para>
Initialisieren und/oder empfangen eines <emphasis>ViewRenderer</emphasis>
Objekts auf Wunsch über den Helfer Broker:
</para>
<programlisting language="php"><![CDATA[
$viewRenderer =
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setView($view)
->setViewSuffix('php');
]]></programlisting>
</listitem>
</itemizedlist>
</note>
</sect4>
<sect4 id="zend.controller.actionhelper.viewrenderer.api">
<title>API</title>
<para>
In seiner einfachsten Verwendung, kann der <emphasis>ViewRenderer</emphasis> ganz
einfach instanziert und an den Aktion Helfer Broker übergeben werden. Der einfachste
Weg Ihn auf einmal zu Instanzieren und Registrieren ist es, die Methode
<methodname>getStaticHelper()</methodname> des Helfer Brokers zu verwenden:
</para>
<programlisting language="php"><![CDATA[
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
]]></programlisting>
<para>
Das erste Mal wenn ein Aktion Controller instanziert wird, triggert er den
<emphasis>ViewRenderer</emphasis> ein View Objekt zu instanzieren. Jedes Mal wenn ein
Controller Instanziert wird, wird die <methodname>init()</methodname> Methode des
<emphasis>ViewRenderer</emphasis>'s aufgerufen, was dazu führt das er die view
Eigenschaft des Aktion Controllers setzt, und <methodname>addScriptPath()</methodname>,
mit einem Pfad relativ zum aktuellen Modul, aufruft; das wird mit einem Klassenprefix
aufgerufen der nach dem aktuellen Modul benannt ist, was effektiv für alle Helfer und
Filterklassen die im Modul definiert werden den Namensraum setzt.
</para>
<para>
Jedes Mal wenn <methodname>postDispatch()</methodname> aufgerufen wird, ruft dieses
<methodname>render()</methodname> für die aktuelle Aktion auf.
</para>
<para>
Als Beispiel kann die folgende Klasse angenommen werden:
</para>
<programlisting language="php"><![CDATA[
// Eine Controller Klasse, foo Modul:
class Foo_BarController extends Zend_Controller_Action
{
// Rendert standardmäßig bar/index.phtml; keine Aktion benötigt
public function indexAction()
{
}
// Rendert bar/populate.phtml mit der Variable 'foo' gesetzt auf 'bar'.
// Da View Objekte beim preDispatch() definiert werden, sind diese
// bereits vorhanden.
public function populateAction()
{
$this->view->foo = 'bar';
}
}
...
// In einem der View Sktipte:
$this->foo(); // Foo_View_Helper_Foo::foo() aufrufen
]]></programlisting>
<para>
Der <emphasis>ViewRenderer</emphasis> definiert auch eine Anzahl von Zugriffspunkten
um das Setzen und Empfangen von View Optionen zu erlauben:
</para>
<itemizedlist>
<listitem>
<para>
<methodname>setView($view)</methodname> erlaubt das Setzen des View Objektes
für den <emphasis>ViewRenderer</emphasis>. Er wird als öffentliche
Klasseneigenschaft <varname>$view</varname> gesetzt.
</para>
</listitem>
<listitem>
<para>
<methodname>setNeverRender($flag = true)</methodname> kann verwendet werden um
das automatische rendern global ein- oder auszuschalten, z.B. für alle
Controller. Wenn er auf <constant>TRUE</constant> gesetzt wird, ruft
<methodname>postDispatch()</methodname> nicht automatisch
<methodname>render()</methodname> im aktuellen Controller auf.
<methodname>getNeverRender()</methodname> empfängt den aktuellen Wert.
</para>
</listitem>
<listitem>
<para>
<methodname>setNoRender($flag = true)</methodname> kann verwendet werden um das
automatische rendern ein- oder auszuschalten. Wenn er auf
<constant>TRUE</constant> gesetzt wird, wird
<methodname>postDispatch()</methodname> <methodname>render()</methodname>
im aktuellen Controller nicht automatisch aufrufen. Diese Einstellung wird
jedesmal zurückgesetzt wenn <methodname>preDispatch()</methodname> aufgerufen
wird (z.B. muß dieses Flag für jeden Controller gesetzt werden für den das
automatische rendern nicht automatisch stattfinden soll).
<methodname>getNoRender()</methodname> empfängt den aktuellen Wert.
</para>
</listitem>
<listitem>
<para>
<methodname>setNoController($flag = true)</methodname> kann verwendet werden um
<methodname>render()</methodname> zu sagen das für Aktion Skripts nicht in
einem Unterverzeichnis gesucht werden soll das nach dem Controller benannt ist
(was das Standardverhalten ist). <methodname>getNoController()</methodname>
empfängt den aktuellen Wert.
</para>
</listitem>
<listitem>
<para>
<methodname>setNeverController($flag = true)</methodname> ist analog zu
<methodname>setNoController()</methodname>, arbeitet aber auf einem globalen
Level -- z.B. wird es nicht für jede ausgeführte Aktion zurückgesetzt.
<methodname>getNeverController()</methodname> empfängt den aktuellen Wert.
</para>
</listitem>
<listitem>
<para>
<methodname>setScriptAction($name)</methodname> kann verwendet werden um das
Aktion Skript zu spezifizieren das gerendert werden soll.
<varname>$name</varname> sollte der Name des Skripts sein, ohne den Datei
Suffix (und ohne das Controller Unterverzeichnis, ausser wenn
<emphasis>noController</emphasis> eingeschaltet wurde). Wenn nicht
spezifiziert, wird nach einem View Skript gesucht das nach der Aktion in
Anfrage Objekt benannt ist. <methodname>getScriptAction()</methodname> empfängt
den aktuellen Wert.
</para>
</listitem>
<listitem>
<para>
<methodname>setResponseSegment($name)</methodname> kann verwendet werden um zu
spezifizieren in welches Segment das nach einem Antwort Objekt benannt ist,
gerendert werden soll. Wenn nicht spezifiziert, wird in das Standard Segment
gerendert. <methodname>getResponseSegment()</methodname> empfängt den aktuellen
Wert.
</para>
</listitem>
<listitem>
<para>
<methodname>initView($path, $prefix, $options)</methodname> kann aufgerufen
werden um den Basis View Pfad, den Klassenprefix für Helfer, Filter Skripts und
<emphasis>ViewRenderer</emphasis> Optionen zu spezifizieren. Es kann eines der
folgenden Flags übergeben werden: <emphasis>neverRender</emphasis>,
<emphasis>noRender</emphasis>, <emphasis>noController</emphasis>,
<emphasis>scriptAction</emphasis>, und <emphasis>responseSegment</emphasis>.
</para>
</listitem>
<listitem>
<para>
<methodname>setRender($action = null, $name = null, $noController =
false)</methodname> erlaubt es <emphasis>scriptAction</emphasis>,
<emphasis>responseSegment</emphasis>, oder <emphasis>noController</emphasis>
in einem Schritt zu übergeben. <methodname>direct()</methodname> ist ein
Alias für diese Methode, und erlaubt es diese Methode einfach vom eigenen
Controller aus aufzurufen:
</para>
<programlisting language="php"><![CDATA[
// Rendert 'foo' statt dem aktuellen Aktion Skript
$this->_helper->viewRenderer('foo');
// Rendert form.phtml zum 'html' Antwort Segment, ohne einen Controller aus dem
// Unterverzeichnis des View Skripts zu verwenden:
$this->_helper->viewRenderer('form', 'html', true);
]]></programlisting>
<note>
<para>
<methodname>setRender()</methodname> und <methodname>direct()</methodname>
stellen das View Sktript nicht dar, sondern setzen Hinweise die
<methodname>postDispatch()</methodname> und
<methodname>render()</methodname> dann verwenden wenn die View dargestellt
wird.
</para>
</note>
</listitem>
</itemizedlist>
<para>
Der Constructor erlaubt es optional das View Objekt und
<emphasis>ViewRenderer</emphasis> Optionen zu übergeben; er akzeptiert die gleichen
Flags wie <methodname>initView()</methodname>:
</para>
<programlisting language="php"><![CDATA[
$view = new Zend_View(array('encoding' => 'UTF-8'));
$options = array('noController' => true, 'neverRender' => true);
$viewRenderer =
new Zend_Controller_Action_Helper_ViewRenderer($view, $options);
]]></programlisting>
<para>
Es gibt einige zusätzliche Methoden für das individualisieren von Pfadspezifikationen
die für das Herausfinden des Basis View Pfades verwendet werden der dem View Objekt
hinzugefügt wird, und den View Skript Pfad der verwendet wird wenn das View Skript zu
dem gerendert werden soll automatisch herausgefunden wird. Diese Methoden nehmen alle
ein oder mehrere der folgenden Platzhalter:
</para>
<itemizedlist>
<listitem>
<para>
<emphasis>:moduleDir</emphasis> zeigt auf das aktuelle Modul Basisverzeichnis
(von der Konvention her das Elternverzeicnis des Controller Verzeichnisses des
Moduls).
</para>
</listitem>
<listitem>
<para>
<emphasis>:module</emphasis> zeigt auf den aktuellen Modulnamen.
</para>
</listitem>
<listitem>
<para>
<emphasis>:controller</emphasis> zeigt auf den aktuellen Controllernamen.
</para>
</listitem>
<listitem>
<para>
<emphasis>:action</emphasis> zeigt auf den aktuellen Aktionsnamen.
</para>
</listitem>
<listitem>
<para>
<emphasis>:suffix</emphasis> zeigt auf das aktuelle Suffix des View Skripts
(welcher über <methodname>setViewSuffix()</methodname> gesetzt werden kann).
</para>
</listitem>
</itemizedlist>
<para>
Die Methoden für das kontrollieren der Pfad Spezifikationen sind:
</para>
<itemizedlist>
<listitem>
<para>
<methodname>setViewBasePathSpec($spec)</methodname> erlaubt die Änderung der
Pfad Spezifikation die verwendet wird um den Basispfad herauszufinden zu dem
das View Objekt hinzugefügt werden soll. Die Standardspezifikation ist
<filename>:moduleDir/views</filename>. Die aktuelle Spezifikation kann
jederzeit durch Verwenden von <methodname>getViewBasePathSpec()</methodname>
erhalten werden.
</para>
</listitem>
<listitem>
<para>
<methodname>setViewScriptPathSpec($spec)</methodname> erlaubt die Änderung der
Pfad Spezifikation die verwendet wird um den Pfad zu einem individuellen View
Skript herauszufinden (ohne den Basis View Skript Pfad). Die Standard
Spezifikation ist <filename>:controller/:action.:suffix</filename>. Die
aktuelle Spezifikation kann jederzeit durch Verwenden von
<methodname>getViewScriptPathSpec()</methodname> erhalten werden.
</para>
</listitem>
<listitem>
<para>
<methodname>setViewScriptPathNoControllerSpec($spec)</methodname> erlaubt die
Änderung der Pfad Spezifkiation die verwendet wird um den Pfad zu einem
individuellen View Skript herauszufinden wenn <emphasis>noController</emphasis>
aktiv ist (ohne den Basis View Skript Pfad). Die Standard Spezifikation ist
<filename>:action.:suffix</filename>. Die aktuelle Spezikifation kann jederzeit
durch Verwenden von
<methodname>getViewScriptPathNoControllerSpec()</methodname> erhalten werden.
</para>
</listitem>
</itemizedlist>
<para>
Für eine feinkörnige Kontrolle über Pfadspezifikationen kann
<link linkend="zend.filter.inflector">Zend_Filter_Inflector</link> verwendet werden.
Im Hintergrund verwendet der <emphasis>ViewRenderer</emphasis> einen Inflector um
bereits Abstimmungen am Pfad durchzuführen. Um auf dem Inflector einzuwirken, damit
entweder ein eigener für die Verwendung gesetzt wird, oder um den Standard Inflector zu
verändern, können die folgenden Methoden verwendet werden:
</para>
<itemizedlist>
<listitem>
<para>
<methodname>getInflector()</methodname> empfängt den Inflector. Wenn bis dahin
keiner im <emphasis>ViewRenderer</emphasis> existiert, wird dieser, anhand der
Verwendung der Standard Regeln, erstellt.
</para>
<para>
Standardmäßig verwendet dieser statische Referenzregeln für das Suffix und
Modulverzeichnis, sowie ein statisches Ziel; das erlaubt verschiedenen
<emphasis>ViewRenderer</emphasis> Eigenschaften den Inflector dynamisch zu
ändern.
</para>
</listitem>
<listitem>
<para>
<methodname>setInflector($inflector, $reference)</methodname> erlaubt das
Setzen eines eigenen Inflectors für die Verwendung mit dem
<emphasis>ViewRenderer</emphasis>. Wenn <varname>$reference</varname>
<constant>TRUE</constant> ist, setzt dieser das Suffix und Modulverzeichnis
als statische Referenz zu <emphasis>ViewRenderer</emphasis> Eigenschaften,
genauso wie das Ziel.
</para>
</listitem>
</itemizedlist>
<note>
<title>Standard Konventionen für das Eruieren</title>
<para>
Der <emphasis>ViewRenderer</emphasis> führt einige Pfad Normalisierungen durch um
das Eruieren von View Skripten einfacher zu machen. Die Standardregeln sind wie
folgt:
</para>
<itemizedlist>
<listitem>
<para>
<emphasis>:module</emphasis>: MixedCase und camelCaseWörter werden durch
Bindestriche getrennt, und der komplette String wird auf
Kleinschreibung geändert. z.B.: "FooBarBaz" wird "foo-bar-baz".
</para>
<para>
Intern verwendet der Inflector die Filter
<classname>Zend_Filter_Word_CamelCaseToDash</classname> und
<classname>Zend_Filter_StringToLower</classname>.
</para>
</listitem>
<listitem>
<para>
<emphasis>:controller</emphasis>: MixedCase und camelCaseWörter werden
durch Bindestriche getrennt; Unterstriche werden in
Verzeichnistrennzeichen konvertiert, und der komplette String wird auf
Kleinschreibung geändert. Beispiele: "<classname>FooBar</classname>" wird
"foo-bar"; "<classname>FooBar_Admin</classname>" wird
"<filename>foo-bar/admin</filename>".
</para>
<para>
Intern verwendet der Inflector die Filter
<classname>Zend_Filter_Word_CamelCaseToDash</classname>,
<classname>Zend_Filter_Word_UnderscoreToSeparator</classname> und
<classname>Zend_Filter_StringToLower</classname>.
</para>
</listitem>
<listitem>
<para>
<emphasis>:action</emphasis>: MixedCase und camelCaseWörter werden durch
Bindestriche getrennt; nicht-anphanummerische Zeichen werden zu
Bindestrichen übersetzt, und der komplette String wird auf
Kleinschreibung geändert. Beispiele: "fooBar" wird "foo-bar"; "foo-barBaz"
wird "foo-bar-baz".
</para>
<para>
Intern verwendet der Inflector die Filter
<classname>Zend_Filter_Word_CamelCaseToDash</classname>,
<classname>Zend_Filter_PregReplace</classname> und
<classname>Zend_Filter_StringToLower</classname>.
</para>
</listitem>
</itemizedlist>
</note>
<para>
Die letzten Teile in der <emphasis>ViewRenderer</emphasis> <acronym>API</acronym> sind
die Methoden für das aktuelle herausfinden von View Skript Pfaden und Rendern von
Views. Diese enthalten:
</para>
<itemizedlist>
<listitem>
<para>
<methodname>renderScript($script, $name)</methodname> erlaubt es ein Skript mit
einem selbst spezifizierten Pfad zu rendern, optional zu einem benannten Pfad
Segment. Wenn diese Methode verwendet wird, ermittelt der
<emphasis>ViewRenderer</emphasis> nicht automatisch den Skriptnamen sondern
übergibt das <varname>$script</varname> Argument direkt der
<methodname>render()</methodname> Methode des View Objekts.
</para>
<note>
<para>
Sobald die View zum Antwort Objekt gerendert wurde, setzt diese
<emphasis>noRender</emphasis> um irrtümliches mehrfaches rendern zum selben
View Skript zu verhindern.
</para>
</note>
<note>
<para>
Standardmäßig handelt
<methodname>Zend_Controller_Action::renderScript()</methodname> in
Vertretung zur <methodname>renderScript()</methodname> Methode des
<emphasis>ViewRenderer</emphasis>'s.
</para>
</note>
</listitem>
<listitem>
<para>
<methodname>getViewScript($action, $vars)</methodname> erstellt den Pfad zu
einem View Skript das auf einer Aktion basiert die übergeben wird, und/oder
allen Variablen die in <varname>$vars</varname> übergeben werden. Schlüssel für
dieses Array können jede der Pfad Spezifikations Schhüssel enthalten
('moduleDir', 'module', 'controller', 'action', und 'suffix'). Jede übergebene
Variable wird verwendet; andernfalls werden Werte die auf der aktuellen Anfrage
basieren angewendet.
</para>
<para>
<methodname>getViewScript()</methodname> verwendet entweder
<emphasis>viewScriptPathSpec</emphasis> oder
<emphasis>viewScriptPathNoControllerSpec</emphasis> basierend auf den
Einstellungen des <emphasis>noController</emphasis> Flags.
</para>
<para>
Wortbegrenzer die in Modul-, Controller- oder Aktionsnamen vorkommen werden mit
Bindestrichen ('-') ersetzt. Deshalb resultiert, wenn der Controllername
'<command>foo.bar</command>' und die Aktion '<command>baz:bat</command>' ist,
die Verwendung der standard Pfad Spezifikation einen View Skript Pfad von
'<filename>foo-bar/baz-bat.phtml</filename>'.
</para>
<note>
<para>
Standardmäßig handelt
<methodname>Zend_Controller_Action::getViewScript()</methodname> in
Vertretung zur <methodname>getViewScript()</methodname> Methode des
<emphasis>ViewRenderer</emphasis>'s.
</para>
</note>
</listitem>
<listitem>
<para>
<methodname>render($action, $name, $noController)</methodname> prüft zuerst ob
entweder <varname>$name</varname> oder <varname>$noController</varname>
übergeben wurde, und wenn dem so ist, wird das betreffende Flag (respektive
responseSegment und noController) im ViewRenderer gesetzt. Dann übergibt er das
<varname>$action</varname> Argument, wenn vorhanden, an
<methodname>getViewScript()</methodname>. Am Ende wird der berechnete View
Skript Pfad an <methodname>renderScript()</methodname> übergeben.
</para>
<note>
<para>
Achtung vor den Nebeneffekten bei der Verwendung von
<methodname>render()</methodname>: Die Werte die für den Anwort Segment
Namen und für das noController Flag übergeben werden sind im Objekt
dauerhaft. Zusätzlich wird noRender gesetzt nachdem das rendern fertig ist.
</para>
</note>
<note>
<para>
Standardmäßig handelt
<methodname>Zend_Controller_Action::render()</methodname> in Vertretung zur
<methodname>render()</methodname> Methode des
<emphasis>ViewRenderer</emphasis>'s.
</para>
</note>
</listitem>
<listitem>
<para>
<methodname>renderBySpec($action, $vars, $name)</methodname> erlaubt es Pfad
Spezifikations Variablen zu übergeben um den View Skript Pfad zu ermitteln der
erstellt werden soll. Es übergibt <varname>$action</varname> und
<varname>$vars</varname> an <methodname>getScriptPath()</methodname> und
übergibt anschließend den resultierenden Skript Pfad und
<varname>$name</varname> an <methodname>renderScript()</methodname>.
</para>
</listitem>
</itemizedlist>
</sect4>
<sect4 id="zend.controller.actionhelper.viewrenderer.basicusage">
<title>Grundsätzliches Beispiel der Verwendung</title>
<example id="zend.controller.actionhelper.viewrenderer.basicusage.example-1">
<title>Grundsätzliche Verwendung</title>
<para>
Am einfachsten, wird einfach der <emphasis>ViewRenderer</emphasis> Helfer mit dem
Helfer Broker in der eigenen Bootstrap Datei, initialisiert und registriert, und
anschließend die Variablen in den Aktion Methoden gesetzt.
</para>
<programlisting language="php"><![CDATA[
// In der Bootstrap Datei:
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
...
// 'foo' Modul, 'bar' Controller:
class Foo_BarController extends Zend_Controller_Action
{
// Rendert standardmäßig bar/index.phtml; keine Aktion benötigt
public function indexAction()
{
}
// Rendert bar/populate.phtml wobei die Variable 'foo' auf 'bar'
// gesetzt wird. Da das View Objekt beim preDispatch() definiert,
// ist es bereits vorhanden.
public function populateAction()
{
$this->view->foo = 'bar';
}
// Rendert nichts da zu einer anderen Aktion weitergeleitet wird;
// die neue Aktion wird jegliches rendern durchführen
public function bazAction()
{
$this->_forward('index');
}
// Rendert nichts da zu einer anderen Lokation weitergeleitet wird
public function batAction()
{
$this->_redirect('/index');
}
}
]]></programlisting>
</example>
<note>
<title>Benamungs Konventionen: Wort Begrenzer in Controller- und Aktionnamen</title>
<para>
Wenn der Controller- oder Aktionsname aus mehreren Wörtern aufgebaut ist, müssen
diese, da der Dispatcher das benötigt, seperiert sein durch die
<acronym>URL</acronym> nach spezifischem Pfad und Wort Begrenzer Zeichen. Der
<emphasis>ViewRenderer</emphasis> ersetzt jeden Pfad Begrenzer den er im
Controllernamen findet mit einem aktuellen Pfad Begrenzer ('/'), und jeden Wort
Begrenzer der gefunden wird mit einem Bindestrich ('-') wenn Pfade erstellt werden.
Deshalb würde ein Aufruf der Aktion <filename>/foo.bar/baz.bat</filename> zu
<methodname>FooBarController::bazBatAction()</methodname> in
<filename>FooBarControll.php</filename> weiterleiten was wiederum
<filename>foo-bar/baz-bat.phtml</filename> darstellen würde; ein Aufruf der Aktion
<filename>/bar_baz/baz-bat</filename> für dazu das
<methodname>Bar_BazController::bazBatAction()</methodname> in
<filename>Bar/BazController.php</filename> dispatched wird (betrachte die
Separation des Pfades) und <filename>bar/baz/baz-bat.phtml</filename> gerendert
wird.
</para>
<para>
Es ist zu beachten das im zweiten Beispiel, das Modul noch immer das Standardmodul
ist, aber das der Controller, wegen der Existenz eines Pfad Separators, den Namen
<classname>Bar_BazController</classname> in
<filename>Bar/BazController.php</filename> empfängt. Der ViewRenderer emuliert die
Controller Verzeichnis Hierarchie.
</para>
</note>
<example id="zend.controller.actionhelper.viewrenderer.basicusage.example-2">
<title>Automatisches rendern ausschalten</title>
<para>
Für einige Aktionen oder Controller, kann es gewünscht sein das automatische Rendern
auszuschalten -- zum Beispiel, wenn eine andere Art von Ausgabe
(<acronym>XML</acronym>, <acronym>JSON</acronym>, etc)
ausgegeben werden soll, oder wenn man einfach nichts ausgeben will. Es gibt zwei
Optionen: Alle Fälle von automatischem Rendern ausschalten
(<methodname>setNeverRender()</methodname>), oder dieses einfach für die aktuelle
Aktion ausschalten (<methodname>setNoRender()</methodname>).
</para>
<programlisting language="php"><![CDATA[
// Baz Controller Klasse, bar Modul:
class Bar_BazController extends Zend_Controller_Action
{
public function fooAction()
{
// Diese Sektion nicht automatisch Rendern
$this->_helper->viewRenderer->setNoRender();
}
}
// Bat Controller Klasse, Bar Modul:
class Bar_BatController extends Zend_Controller_Action
{
public function preDispatch()
{
// Die Aktionen dieses Controller nie automatisch Rendern
$this->_helper->viewRenderer->setNoRender();
}
}
]]></programlisting>
</example>
<note>
<para>
In den meisten Fällen, macht es keinen Sinn das automatische Rendern global
auszuschalten (ala <methodname>setNeverRender()</methodname>), da das einzige das
man dann vom <emphasis>ViewRenderer</emphasis> erhält das automatische Setup des
View Objekts ist.
</para>
</note>
<example id="zend.controller.actionhelper.viewrenderer.basicusage.example-3">
<title>Ein anderes View Skript auswählen</title>
<para>
Einige Situationen erfordern das ein anderes Skript, als das nach der Aktion
benannte, ausgeführt wird. Zum Beispiel, wenn man einen Controller hat der Aktionen
sowohl hinzufügen als auch bearbeiten kann, und beide mit der selben 'form' View
angezeigt werden, aber mit unterschiedlichen Werten gesetzt werden. Der Skript Name
kann ganz einfach geändert werden. Entweder mit
<methodname>setScriptAction()</methodname>, <methodname>setRender()</methodname>
oder durch Aufruf des Helfers als Methode, was wiederum
<methodname>setRender()</methodname> ausruft.
</para>
<programlisting language="php"><![CDATA[
// Bar Controller Klasse, foo Modul:
class Foo_BarController extends Zend_Controller_Action
{
public function addAction()
{
// Rendert 'bar/form.phtml' statt 'bar/add.phtml'
$this->_helper->viewRenderer('form');
}
public function editAction()
{
// Rendert 'bar/form.phtml' statt 'bar/edit.phtml'
$this->_helper->viewRenderer->setScriptAction('form');
}
public function processAction()
{
// einige Prüfungen durchführen...
if (!$valid) {
// Rendert 'bar/form.phtml' statt 'bar/process.phtml'
$this->_helper->viewRenderer->setRender('form');
return;
}
// andernfalls die Bearbeitung weiter durchführen...
}
}
]]></programlisting>
</example>
<example id="zend.controller.actionhelper.viewrenderer.basicusage.example-4">
<title>Die resigstrierte View ändern</title>
<para>
Was wenn ein View Objekt modifiziert werden soll -- zum Beispiel, die Helfer Pfade
ändern, oder die Kodierung? Das kann durch Modifikation des View Objekts, das im
Controller gesetzt ist, gemacht werden, oder durch herausnehmen des View Objekts
aus dem <emphasis>ViewRenderer</emphasis>; beide referenzieren auf das gleiche
Objekt.
</para>
<programlisting language="php"><![CDATA[
// Bar Controller Klasse, foo Modul:
class Foo_BarController extends Zend_Controller_Action
{
public function preDispatch()
{
// Die Kodierung der View ändern
$this->view->setEncoding('UTF-8');
}
public function bazAction()
{
// Das View Objekt erhalten, und den Kommentar Callback
// auf 'htmlspecialchars' setzen
$view = $this->_helper->viewRenderer->view;
$view->setEscape('htmlspecialchars');
}
}
]]></programlisting>
</example>
</sect4>
<sect4 id="zend.controller.actionhelper.viewrenderer.advancedusage">
<title>Erweiterte Beispiel der Verwendung</title>
<example id="zend.controller.actionhelper.viewrenderer.advancedusage.example-1">
<title>Die Pfad Spezifikationen ändern</title>
<para>
In einigen Fällen, kann man entscheiden das die standardmäßige Pfad Spezifikation
nicht den Notwendigkeiten der Seite entspricht. Zum Beispiel, wenn man einen
einzelnen Template Baum haben will zu dem man dann Zugriff für Entwickler geben kann
(das ist sehr typisch wenn man zum Beispiel <ulink
url="http://smarty.php.net/">Smarty</ulink> verwendet). In solchen Fällen, kann
es gewünscht sein die Spezifkiation des View Basispfades hardkodiert zu erstellen
und eine alternative Spezifikation für die Pfade der Aktions View Skripte selbst zu
erstellen.
</para>
<para>
Für die Zwecke dieses Beispiels, nehmen wir an das der Basispfad zur View
'<filename>/opt/vendor/templates</filename>' sein soll, und das die View Skripte
durch '<filename>:moduleDir/:controller/:action.:suffix</filename>' referenziert
werden sollen; wenn das <emphasis>noController</emphasis> Flag gesetzt wurde, soll
aus dem Top Level statt aus einem Unterverzeichnis gerendert werden
('<filename>:action.:suffix</filename>'). Zuletzt soll 'tpl' als View Skript Suffix
für Dateinamen verwendet werden.
</para>
<programlisting language="php"><![CDATA[
/**
* In der Bootstrap Datei:
*/
// Unterschiedliche View Implmentation
$view = new ZF_Smarty();
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setViewBasePathSpec('/opt/vendor/templates')
->setViewScriptPathSpec(':module/:controller/:action.:suffix')
->setViewScriptPathNoControllerSpec(':action.:suffix')
->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
]]></programlisting>
</example>
<example id="zend.controller.actionhelper.viewrenderer.advancedusage.example-2">
<title>Mehrfache View Skripte von der gleichen Aktion rendern</title>
<para>
Manchmal, ist es notwendig mehrfache View Skripte von einer einzelnen Aktion zu
rendern. Das ist sehr geradlinig -- einfach mehrere Aufrufe zu
<methodname>render()</methodname> machen:
</para>
<programlisting language="php"><![CDATA[
class SearchController extends Zend_Controller_Action
{
public function resultsAction()
{
// Annahme das $this->model das aktuelle Modell ist
$this->view->results =
$this->model->find($this->_getParam('query', '');
// render() handelt standardmäßig in Vertretung zum ViewRenderer
// Rendert zuerst die Such Form und anschließend die Ergebnisse
$this->render('form');
$this->render('results');
}
public function formAction()
{
// tue nichts; der ViewRenderer bearbeitet das View Skript automatisch
}
}
]]></programlisting>
</example>
</sect4>
</sect3>
|