hook_form() und Nichtform-Seitenelemente
![](https://www.drupalcenter.de/files/imagecache/upic_mini/pictures/picture-110.jpg)
am 05.12.2007 - 12:29 Uhr in
Thema eigenes Modul mit eigenem Nodetype.
In Normalfall werden mit dem Gespann hook_form(), hook_nodeapi(), hook_view() die einzelnen Elemente des Nodetypes "behandelt". In hook_form() definierte Formelemente erscheinen im Bearbeitenformular. Im einfachsten Fall wird dabei das Formelement 'body' auch in der Nodeansicht verwendet. Dieses Formelement ist beim Bearbeiten eine Textarea und in der Nodeansicht ein div/p.
Nun ergeben sich fuer mich die 2. Fragen.
1.
Wie definiere ich weitere (Formel)Emente (Textareas) um sie bei der Nodeansicht angezeigt zu bekommen?
'body' ist ja schon belegt.
2.
Wie definiere ich Elemente, die bei der Nodeansicht angezeigt werden aber beim Bearbeiten kein Formelement wie bspw. eine Textarea sind?
Normalerweise kann ich ja in hook_form() nur Formelemente definieren.Ich muesste quasi ein Nichtformelement definieren. Mein Ziel ist die Verwendung eines div beim Bearbeitenformular welches dann auch in der Nodeansicht angezeigt wird. Im Bearbeitenformular soll dieses div einfach nur gezeigt werden.
Man kann sich zwar mit Tricksen behelfen indem man der '#description' ein div unterjubelt aber insgesamt funktioniert das nicht - wie mein Thread deutlich macht.
Hier stosse ich momentan an Grenzen. Scheinbar ist auch nichts dokumentiert bzw. es ist nicht machbar.
---------------------------
quiptime
- Anmelden oder Registrieren um Kommentare zu schreiben
hook_nodeapi ist nicht für dich gedacht
am 05.12.2007 - 13:39 Uhr
In Normalfall werden mit dem Gespann hook_form(), hook_nodeapi(), hook_view() die einzelnen Elemente des Nodetypes "behandelt".
hook_nodeapi
ist eigentlich für Module gedacht, die das Verhalten von Inahltstypen verändern, die sie nicht selbst bereitstellen. Für Inhaltstypen, die ein Modul selbst bereitstellt gibt es die Hookshook_form
hook_validate
hook_submit
hook_insert
hook_update
hook_load
hook_view
hook_delete
Wie definiere ich weitere (Formel)Emente (Textareas) um sie bei der Nodeansicht angezeigt zu bekommen?
hook_form
das Formularelement definieren.hook_validate
prüfen ob der Benutzer gültige Daten eingetragen hat.hook_insert
und hook_update Daten in die Datenbank schreibenhook_load
die aus der Datenbank ladenhook_view
die Daten in das $node->content Array eintragenWie definiere ich Elemente, die bei der Nodeansicht angezeigt werden aber beim Bearbeiten kein Formelement wie bspw. eine Textarea sind?
Du kannst eigene Formularelemente definieren. Vielleicht reicht aber auch eine markup'-, 'item'- oder 'value'-Element. Siehe Forms API Reference
--
![XING](http://www.xing.com/img/buttons/6_de_btn.gif)
Mit dem Verweis auf
am 05.12.2007 - 14:23 Uhr
Mit dem Verweis auf hook_view in hook_nodeapi habe ich also einen ueberfluessigen Schritt realisiert.
Nun zum Anlegen weiterer Formelemente. Um 'body' muss ich mich nicht kuemmern - wird bereits ohne eigene Statements in hook_insert, hook_update und hook_load ueber die Tabelle node_revisions erledigt.
Wenn ich nun weitere Formelemente anlege muss ich mich ja wohl selbst um Statements fuer hook_insert, hook_update und hook_load kuemmern. D. h., der Inhalt dieser Formelemente wird nicht automatisch in node_revisions abgelegt?
Zumindest ist es momentan so, das der Inhalt eines weiteren Formelementes (Textarea), in hook_form als $form['foo'] definiert, nicht in node_revisions landet.
Ich muss also den Inhalt weiterer Formelemente in der zum Nodetype des Modules gehoerenden Tabelle durch eigene Aktionen speichern, aendern und laden.?
Sehe ich das richtig so?
Naja, und die Forms API Reference werde ich mir genau ansehen.
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Richtig
am 05.12.2007 - 16:28 Uhr
Ich muss also den Inhalt weiterer Formelemente in der zum Nodetype des Modules gehoerenden Tabelle durch eigene Aktionen speichern, aendern und laden.?
Richtig. Eigene Tabellen legst du in
hook_install
an. Die Tabelle sollte die Spaltevid
haben. Oft haben sie noch eine Spaltenid
, ich weiß nicht wozu, eigentlich ist sie redundant; auf dienid
kannst du mittelINNER JOIN {node_revisions} USING(vid)
zugreifen.--
![XING](http://www.xing.com/img/buttons/6_de_btn.gif)
verdammte Form API
am 05.12.2007 - 23:31 Uhr
Das Hantieren mit der DB hatte ich schon so geloest.
Nun versuche ich immer noch ein zusaetzliches Formelement zu verwenden. Bsp. Textarea. Im Bearbeitenformular ist es da und Daten/Aenderungen im Textbereich werden gespeichert.
Aber ich kann machen was ich will, dieses Formelement erscheint nicht in der Nodeansicht und deswegen wohl auch nicht in der Preview. Ich sehe den Inhalt mit print_r().
Muss ich in hook_view() noch irgend was unternehmen damit es angezeigt wird? Oder mache ich schon beim Erstellen in hook_form() was falsch? Oder vergesse ich irgendwas?
So erstelle ich:
<?php
$form['blubber']['foo'] = array(
'#type' => 'textarea',
'#default_value' => $node->foo ? $node->foo : 'Hallo',
);
?>
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Du mußt Forms API Elemente in $node->content eintragen
am 06.12.2007 - 09:00 Uhr
Muss ich in hook_view() noch irgend was unternehmen damit es angezeigt wird?
Ja. Du mußt die Daten in das $node->content Array eintragen. Ein Beispiel gibt's im Quelltext von node_example.module. Im Endefekt läuft es meistens darauf hinaus, das du Formularelemente des Typs 'markup' definierst und dort die Eigenschaft '#value' setzt.
--
![XING](http://www.xing.com/img/buttons/6_de_btn.gif)
@traxer, if ($page) ?
am 06.12.2007 - 13:32 Uhr
1.
Wenn ich es so mache werden alle definierten Formelemente angezeigt.
<?php
function node_example_view($node, $teaser = FALSE, $page = FALSE) {
$node = node_prepare($node, $teaser);
$node->content['myfield'] = array(
'#value' => $node->myfield,
);
return $node;
}
?>
Preview beim Bearbeiten zeigt die zusaetzlich zum body definierten Formelemente - ok. Aber, wenn ich den Term aufrufe der einen solchen Node listet werden alle Formelemente angezeigt obwohl nur der Teaser zu sehen sein sollte - nicht ok.
2.
Wenn ich es so mache werden nicht immer alle definierten Formelemente angezeigt.
<?php
function node_example_view($node, $teaser = FALSE, $page = FALSE) {
$node = node_prepare($node, $teaser);
if ($page) {
$node->content['myfield'] = array(
'#value' => $node->myfield,
);
}
return $node;
}
?>
Wenn ich den Term aufrufe der einen solchen Node listet wird nur der Teaser angezeigt - ok. Preview beim Bearbeiten zeigt nur den Teaser - nicht ok.
Also muesste ich eigentlich Variante 1. verwenden und dabei zusaetzlichen Formelementen sagen das sie bei Termansichten nicht angezeigt werden. Aehnlich wie wie man es mit CCK Feldern machen kann - denn die Verhalten sich korrekt.
Gibt es ausser if ($page) weitere Schalter?
Gibt es fuer Formelemente einen "Taeser-Parameter"?
-----------------------------------------------------------------------
Und genau an dieser Stelle schweigt sich node_example aus. Auch alle sonstigen Dokus zum Thema hook_view() gehen nicht auf diese Problematik ein.
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Preview: $teaser == false && $page == false;
am 06.12.2007 - 14:17 Uhr
In der API-Referenz von hook_view steht ja:
$teaser Whether we are to generate a "teaser" or summary of the node, rather than display the whole thing.
$page Whether the node is being displayed as a standalone page.
Ich verstehe das so:
$teaser == false; $page == true;
$teaser == true; $page == false;
$teaser == false; $page == false;
Ein Preview ist weder ein Teaser, noch eine eigene Seite.
--
![XING](http://www.xing.com/img/buttons/6_de_btn.gif)
Preview: $teaser = true; $page = true;
am 06.12.2007 - 15:01 Uhr
Ein Preview ist $teaser und $page zugleich. So gesehen keine eigene Seite, aber er zeigt die Inhalte Beider zugleich. Damit ist
Anzeige als Preview
$teaser == false; $page == false;
nicht richtig.
Denn in der Preview sehe ich ja $easer und $page. Aber leider $page nicht mit allen Formelementen sondern nur mit $form['body'] - mein Problem.
Aber diese Erkenntnis bring mich kein Stueck weiter.
-------------------------------------------------------------------------
1. Anzeige auf eigener Seite
$teaser = false; $page = true;
2. Anzeige in Listen
$teaser = true; $page = false;
3. Anzeige als Preview
$teaser = true; $page = true;
Das waere aus meiner Sicht richtig. Die Fragen sind:
Wie erreiche ich bei 1. das nur der Teaser angezeigt wird?
Wie erreiche ich das Formelemente ausser 'body' nicht dem Teaser zugeordnet werden?
Wie erreiche ich bei 3. das auch weitere Formelemente ausser 'body' angezeigt werden?
Um Missverstaendnisse auszuschliessen. Ich meine keine CCK Formelemente sondern nur mit einem Modul erzeugte.
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
$page == true heißt "als eigene Seite", nicht "kompletter Node"
am 06.12.2007 - 15:29 Uhr
Damit ist
Anzeige als Preview
$teaser == false; $page == false;
nicht richtig. Denn in der Preview sehe ich ja $easer und $page.
Drupal argumentiert da anders. Drupal meint: "Ich will im Preview den Teaser anzeigen, also rufe ich
hook_view($node, true, false)
auf."Drupal argumentiert weiter: "Ich will im Preview auch den kompletten Node anzeigen, aber nicht als eigene Seite. Also rufe ich
hook_view($node, false, false)
auf."Für einen Preview ruft theme_node_preview als zwei mal hook_view auf, mit unterschiedlichen Argumenten.
Ich hoffe damit sind auch die in deinem Beitrag weiter unten stehenden Fragen geklährt.
--
![XING](http://www.xing.com/img/buttons/6_de_btn.gif)
@traxer, Groschen ist gefallen
am 07.12.2007 - 00:25 Uhr
@traxer,
Danke Dir für Deine Geduld. Hat 'ne Weile gedauert aber jetzt ist der Groschen gefallen.
Übrigens,
für das Formelement der Googlemap verwende ich nun hook_elements().
Für Nachleser
Anzeigen weiterer, zusätzlich zu $form['body'], definierter Formelemente bei der Preview:
<?php
function mymodule_view($node, $teaser = FALSE, $page = FALSE) {
$node = node_prepare($node, $teaser);
if ($teaser == 0 && !$page) {
$node->content['extra_foo'] = array(
'#value' => $node->extra_foo,
);
}
if ($page) {
$node->content['extra_foo'] = array(
'#value' => $node->extra_foo,
);
}
return $node;
}
?>
Die beiden if kann man auch zusammenlegen aber wegen der besseren Verständlichkeit habe ich es mal so geschrieben.
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.