[gelöst] Node Reference als Comma-seperated list
am 05.07.2010 - 18:09 Uhr in
Hallo zusammen,
ich hab einen ContentTypen A mit einer CCK Node Reference zu ein oder mehreren ContentTypen B. Funktioniert auch alles großartig. Mit Views generiere ich jetzt eine Liste aus allen ContentTypen A und gebe dabei auch die jeweiligen Node References aus. Das funktioniert ebenfalls und zeigt mir die Titel (Formatter ist auf Titel) an, jedoch mit automatisch generierten <div>
-tags. Das kann man verhindern indem man "Strip HTML Tags" auswählt, allerdings werden die Titel dann direkt hintereinander geschrieben (titel1titel2titel3). Kann ich die Ausgabe so beeinflussen das ich eine "komma-getrennte" Liste generiert bekomme (titel1, titel2, titel)?
Grüße,
Milchbar.
- Anmelden oder Registrieren um Kommentare zu schreiben
Mmmh, man könnte innerhalb
am 05.07.2010 - 20:11 Uhr
Mmmh, man könnte innerhalb von Views z.B. folgendes machen:
Man nimmt sich das Modul Views Custom Field und fügt damit in seiner View ein Custom PHP-Feld ein.
Dann kann man in diesem Feld z.B. folgenden PHP-Code verwenden:
<?php
//Das Node-Reference-Feld heißt article_reference
$werte = $data->node_data_field_article_nodereference_field_article_nodereference_nid;
$ausgabe = '';
foreach ($werte as $key => $value){
$mynode = node_load($value);
$ausgabe .= $mynode->title . ', ';
}
?>
Dann noch per substr() die letzten beiden Zeichen absägen und fertig.
Allerdings bleibt dabei die Frage, wie performant die Sache ist, weil man immer das Node-Objekt läd. Wenn auf einer Seite viele Nodes mit mehreren Node-Referenzen geladen werden, kommen schnell einige Nodes zusammen, das könnte dann schwierig werden.
Alternativ könnte man statt node_load eine SQL-Abfrage machen und direkt den Titel des entsprechenden Nodes laden, geht glaube ich schneller als den Node zu laden. Und bietet sich vor allem an, wenn abzusehen ist, dass es häufig mehrere Referenzen pro Node gibt. Dann könnte man sich alle referenzierten Node-IDs raus holen, damit eine einzelne Abfrage machen und dann nacheinander die Titel raus holen. Eine Query und eine While-Schleife mit 4 Durchgängen geht denke ich mal schneller als 4 Node-Objekte zu laden.
Dürfte auf jeden Fall funktionieren, es kann aber gut sein, dass es noch eine viel bessere Lösung gibt (z.B. über Theming). War nur gerade das erste, was mir eingefallen ist.
Sieh an, das Modul kannte ich
am 05.07.2010 - 20:43 Uhr
Sieh an, das Modul kannte ich noch nicht. Allerdings scheint mir der Lösungsansatz für meinen Fall nicht performant genug zu sein. Vielleicht gibt es noch eine andere Möglichkeit udn ich gehe die Lösung meines Problems nur falsch an.
Zur Veranschaulichung vielleicht nochmal folgendes:
Ich habe 2 Contenttypen (Projekt und Diensleistung). Jedes Projekt hat eine oder mehrere Diensleistungen als Node Reference gespeichert. Mit dem View möchte ich jetzt eine Liste aus allen Projekten in folgendem Format generieren - das Format ist wichtig damit ich im Frontend mit jQuery filtern kann:
<li class="DiensleistungRefA, DiensleistungRefB">Projektname</li>
...
Es kann durchaus vorkommen das ein Projekt bis zu 10 Diensleistungen als Referenz gespeichert hat. Daher scheint mir das Auslesen jeder Node als zu (performance-)aufwändig. Auch via Theming bietet sich hier natürlich wenig an.
Mit den Einstellungen im Anfangs-Post bekomme ich die Ausgabe eben nur fast hin. Zum Vergleich:
<li class="DiensleistungRefADiensleistungRefB">Projektname</li>
...
Die Titel werden so ohne Trennzeichen aneinander gereiht.
Danke schonmal für die hilfreichen Tipps!
Mmmh, wie wäre es mit diesem
am 05.07.2010 - 22:31 Uhr
Mmmh, wie wäre es mit diesem Ansatz:
in deinem Theme-Ordner gibt's eine Datei namens template.php, dort überschreibst du die theme-Funktionen der Nodereference. Es gibt für jeden Formatter eine eigene Theme-Funktion, die man überschreiben kann. Das könnte zum Beispiel so aussehen:
<?php
//So sieht die Funktion standardmäßig aus:
function theme_nodereference_formatter_default($element) {
$output = '';
if (!empty($element['#item']['safe']['nid'])) {
$output = l($element['#item']['safe']['title'], 'node/'. $element['#item']['safe']['nid']);
if (!$element['#item']['safe']['status']) {
$output = '<span class="node-unpublished"> '. t('(Unpublished)') ." $output</span>";
}
}
return $output;
}
//Daraus könnte man folgendes machen:
//das "theme" im Funktionsnamen ersetzt man durch den Namen seines Themes, meines heißt "pixture_reloaded".
function pixture_reloaded_nodereference_formatter_default($element) {
$output = '';
if (!empty($element['#item']['safe']['nid'])) {
$output = l($element['#item']['safe']['title'], 'node/'. $element['#item']['safe']['nid']) . ', ';
if (!$element['#item']['safe']['status']) {
$output = '<span class="node-unpublished"> '. t('(Unpublished)') ." $output</span>";
}
}
return $output;
}
//Es wird also ein Komma mit Leerzeichen hinter jedem Node-Referenz-Link ausgegeben.
?>
Und dann kommt Views ins Spiel. Dort hast du links unter "Basiseinstellungen" ganz unten den Punkt "Theme: Information".
Wenn du dort drauf klickst, siehst du, mit welchen Template-Dateien welche Inhalte gethemed (blödes Wort...) werden. Dort dürfte auch dein Nodereference-Feld auftauchen und dahinter stehen allerlei tpl.php-Bezeichnungen. Dabei gilt: Je weiter hinten die Bezeichnung steht, desto spezieller bezieht sie sich auf dieses eine Feld. Beispiel:
Mein Feld heißt article_nodereference. Unter Theme: Information stehen einige Bezeichnungen. An erster stelle steht dort "views-view-field.tpl.php". Wenn ich die verändere, verändert sich die Ausgabe ALLER Felder auf der gesamten Website, weil die Bezeichnung eben sehr allgemein ist.
An letzter Stelle dieser Liste steht z.B. "views-view-field--test-view--default--field-article-nodereference-nid.tpl.php". Wenn ich eine solche Datei ändern würde, dann würde sich nur die Ausgabe dieses NodeReference-Feldes in der Standard-Ansicht meiner View "Test-View" ändern. Prinzip verstanden?
Also suche ich mir eines aus der Mitte (je nachdem, was man braucht), nämlich "views-view-field--field-article-nodereference-nid.tpl.php", welches bedeutet dass die Ausgabe dieses NodeReference-Feldes in allen Views mit dieser Datei gesteuert wird. So musst du dir eben auch die passende Bezeichnung aussuchen.
Dann gehst du in den Ordner sites/all/modules/views/theme. Dort kopierst du dir die Standard-Datei views-view-field.tpl.php und fügst sie in den Ordner deines Themes ein (niemals im Modul-Ordner die tpl.phps anpassen, sondern immer in den Theme-Ordner kopieren). Diese Datei bennenst du nun entsprechend der oben gewählten Theme-Info um.
Standardmäßig hat diese Datei nur eine Zeile:
<?php
print $output;
?>
Das kann man nun ein wenig anpassen, z.B. so:
<?php
$output = strip_tags($output);
print $output;
?>
Damit werden alle HTML-Tags entfernt. Also würden die Referenz-Links wieder zusammenstehen, klar. Aber da wir vorher in der template.php die theme-Funktion geändert haben, steht nun ein zwischen jedem Link ein Komma.
Theoretisch könnte man auch nur die theme-Funktion schreiben und dann bei Views einen Haken bei "Strip all HTML Tags" machen. Aber dann sind alle weg, wenn man zum Beispiel die Links beibehalten will, kann man bei strip_tags bestimmte Tags erlauben und belassen.
Außerdem muss man sich noch Gedanken machen, wie man die letzten beiden Zeichen entfernt (Komma und Leerzeichen hinter dem letzten Link, die stören ja wahrscheinlich). Dürfte aber auch kein Problem sein, wenn bei strip_tags z.B. nur Links zugelassen werden, dann entfernt man einfach die letzten 6 Zeichen (Link-Tag, Komma, Leerzeichen) und bastelt den Link-Tag wieder ran oder nimmt nur die zwei Zeichen an der Stelle raus, sowas geht dann eben nur in der tpl.php, nicht in Views selbst (glaube ich). Diese Lösung dürfte auch recht performant sein, schließlich schreibt man nur den Output etwas um. Und ist auch nicht weiter schwer umzusetzen. In der template.php kann man dann auch noch ein paar Anpassungen vornehmen, eigentlich stehen einem auf diese Art einige Möglichkeiten offen.
Wichtig: Nachdem man die neue tpl.php im Theme-Ordner angelegt hat, muss man die Theme-Registry neu aufbauen, damit sie auch erkannt wird. Danach werden Änderungen an der Datei sofort nach dem Speichern (und neu laden der Seite) erkannt. Die Theme-Registry kann man neu aufbauen, indem man unter "Leistung" (bei den Seiten-Einstellungen) den Cache leert oder indem man admin/build/modules oder admin/build/themes aufruft.
Probier's mal aus, könnte evtl. eine ganz gute Lösung für dich sein.
Super! Vielen Dank für den
am 06.07.2010 - 06:52 Uhr
Super! Vielen Dank für den ausführlichen Bericht! Die Sache mit den Theming-Infos der Views war mir zwar schon bekannt. Das ich die Default-Formatter einfach überschreiben kann nicht. :) Hat auch direkt funktioniert. Danke für diesen wertvollen Hinweis. Könnte sich in Zukunft öfter mal als nützlich erweisen!
Beste Grüße,
Milchbar
Dann bearbeite doch noch den
am 06.07.2010 - 17:56 Uhr
Dann bearbeite doch noch den ersten Beitrag hier und setze ein [gelöst] vor den Titel, damit es übersichtlich bleibt ;-)
(Wann kommt endlich das "Gelöst"-Flag? ^^)
Übrigens, in der template.php kann man alle "themebaren Funktionen" überschreiben, also Funktionen, die in einem Modul mit "theme_" beginnen.
Dazu kann man sich das hier mal anschauen:
http://www.drupalcenter.de/handbuch/17423