verschiedene Views je nach URL-Hierarchie
am 09.12.2007 - 21:16 Uhr in
Hallo zusammen,
ich möchte für folgende URL-Situationen verschiedene Views haben, ohne dafür jeweils eine eigene View erstellen zu müssen.
/world/kontinent/
/world/kontinent/land/
/world/kontinent/land/stadt/
Also, z.B. soll unter www.beispiel.de/world/europa alle Nodes aus Europa erscheinen. Unter www.beispiel.de/world/europa/spanien alle Nodes aus Spanien und eben unter www.beispiel.de/world/europa/spanien/madrid nur die aus Madrid.
In meinen Nodes werden mittels drei CCK-Textfields die Kontinent/Land/Stadt Informationen mitgegeben.
Fangen wir mal mit der Stadt-View an:
Page View: URL: world
Argument-Type: Text: city (field_city) - Display all values
Argument Code: $args[0] = arg(3); return $args;
Das funktioniert soweit auch ganz gut. Also ich rufe z.b. www.beispiel.de/world/europa/spanien/madrid auf und bekomme tatsächlich auch nur die nodes von Madrid.
Allerdings wenn ich mit dem gleichen Schema bei der Land-View weitermache, also:
Page View: URL: world
Argument-Type: Text: country (field_country) - Display all values
Argument Code: $args[0] = arg(2); return $args;
Dann bekomme ich beim Aufruf von www.beispiel.de/world/europa/spanien einen "Page not found".
Lösche ich die Stadt-View, dann funktioniert die Land-View einwandfrei!
Ich bin ehrlich und sage gleich, dass ich das mit den Argumenten und auch mit dem Argument Handling Code noch nicht ganz gerafft habe.
Kann mir jemand bei meinem Anliegen weiterhelfen?
- Anmelden oder Registrieren um Kommentare zu schreiben

Selbst ist der Bastler ;-)
am 10.12.2007 - 11:13 Uhr
So, nach einigem rumprobieren und immer noch nicht so ganz durchblicken, wie das mit den Argumenten in Views läuft, bin ich doch auf eine Lösung meines Problems gestoßen - wen´s interessiert:
Einstellungen für Kontinent:
Page View: URL: world/$arg
Argument-Type: Text: continent (field_continent)
Argument Code: --- hab ich ganz weggelassen
Einstellungen für Land:
Page View: URL: world/$arg/$arg
Argument-Type:
Text: country (field_country)
Text: continent (field_continent)
Argument Code: --- hab ich ganz weggelassen
Einstellungen für Stadt:
Page View: URL: world/$arg/$arg/$arg
Argument-Type:
Text: country (field_country)
Text: continent (field_continent)
Text: city (field_city)
Argument Code: --- hab ich ganz weggelassen
Falls jemand eine bessere/schönere Lösung hat, fühlt Euch frei und postet sie. Vielleicht kann mir dann in diesem Zuge gleich jemand erklären, wie das mit den Views Argumenten funktioniert. Hab jetzt schon zig mal die englische Dok durchgelesen, aber irgendwie werde ich daraus nicht schlau!
Hast du jetzt drei Views?
am 10.12.2007 - 12:01 Uhr
Die ersten zwei Views kannst du weglassen. Den Standardwert für die Argumente setzt du "Display all values".
--

Wenn ich das Modul Views wäre
am 10.12.2007 - 12:05 Uhr
Fangen wir mal mit der Stadt-View an:
Page View: URL: world
Allerdings wenn ich mit dem gleichen Schema bei der Land-View weitermache, also:
Page View: URL: world
Lösche ich die Stadt-View, dann funktioniert die Land-View einwandfrei!
Logisch. Wenn ich das Modul Views wäre wurde ich mich auch so verhalten.
Dein Problem ist, das Stadt-View und Land-View die gleiche URL haben. Aber das hast Du ja schon selber gemerkt.
-------------
quiptime
Nur tote Fische schwimmen mit dem Strom.
Muss alle drei Views haben
am 10.12.2007 - 13:28 Uhr
@traxer: Ich hab testweise die ersten zwei Views (also Kontinent und Land) gelöscht und die Argumente auf "Display all values" gesetzt. Bei Eingabe von z.B. www.beispiel.de/world/europa bzw. auch bei www.beispiel.de/world/europa/polen kommt "Page not found". Nur bei www.beispiel.de/world/europa/polen/warschau kommen die entsprechenden Nodes. Dein Ansatz funktioniert bei mir also nicht - ausser ich hab was übersehen?
@all: gibts irgendwo ne gute Anleitung/Doku zu den Views/Argumente. Leider komme ich mit der Doku bei drupal.org nicht zurecht.
Mit drei Views ist wohl aber
am 10.12.2007 - 13:45 Uhr
Mit drei Views ist wohl aber nicht das gelbe vom Ei. An und für sich funktioniert meine Lösung (siehe oben) allerdings machen mir jetzt die Breadcrumbs Sorgen bzw. daran sieht man, dass meine Lösung nicht so dolle ist.
Die Breadcrumbs werden über den Titel generiert - richtig? Also folgende Einstellungen bei Argument-Type Title:
für Kontinent: Text: continent (field_continent): Title: %1
für Land: Text: country (field_country): Title: %2
für Stadt: city (field_city): Title: %3
Der Titel der Seite wird schön brav angezeigt, also bei z.B. www.beispiel.de/world/europa/polen eben "polen".
Beim Breadcrumb soweit auch alles super, ausser dass ich hintendran leere ">" hab, also bei www.beispiel.de/world/europa/polen/warschau folgender breadcrumb:
Home › europa › polen › › ›
(Groß-/Kleinschreibung sollte ich auch noch hinbekommen!)
Verwende URL "world"
am 10.12.2007 - 14:21 Uhr
Bei Eingabe von z.B. www.beispiel.de/world/europa bzw. auch bei www.beispiel.de/world/europa/polen kommt "Page not found".
Verwende "world" als URL.
$argmusst du nur dann angeben, wenn das Argument mitten in der URL steht; am Ende der URL werden sie automatisch verarbeitet.Argumente, die du bei der Konfiguration des Views in der URL angibst, sind sozusagen Pflichtangaben. Um anzudeuten, das du eine solche Pflichtangabe nicht machen willst, kannst du es beim Aufruf des Views durch eine Wildcard ersetzen. Welcher Wert als Wildcard interpretiert wird, stellst du in der Konfiguration des jeweiligen Argumentes ein.
Wenn du am Ende der URL explizit $arg angibst, dann musst du diese Wildcard beim Aufruf des Views übergeben.
Beispiel: Stehen in den Wildcard-Feldern jeweils "*", und die URL ist
world/$arg/$arg/$arg, dann musst den View aufrufen über die URLworld/*/*/*--

Hurra - es funktioniert
am 10.12.2007 - 15:36 Uhr
@traxer: Tausend Dank. Funktioniert jetzt mit nur einer View!
Hat man das eine Problem gelöst, kommt das nächste
am 10.12.2007 - 17:16 Uhr
Jetzt scheitere ich an den Umlauten oder auch Seperator-Zeichen. Wie kann ich Views beibringen, dass z.B. "Bad Wörishofen" gleich "bad-woerishofen" ist? Gibts hierzu eine Möglichkeit, evlt. über den Argument Handling Code?
something like this
am 10.12.2007 - 17:50 Uhr
Das funktioniert auch schon:
if( $args[2] == 'bad-woerishofen' ) {$args[2] = 'Bad Wörishofen';
}
return $args;
Allerdings kann ich das wohl nicht händisch bei 1000en von Orten machen?!
Trotzdem nicht schlecht!
am 10.12.2007 - 23:44 Uhr
Allerdings kann ich das wohl nicht händisch bei 1000en von Orten machen?!
Aber der Ansatz ist gut. Die Zuordnung ist doch bestimmt irgendwo in der Datenbank gespeichert.
--

DB-Abgleich
am 11.12.2007 - 14:40 Uhr
Ja, traxer so hab ich dann auch gemacht. Folgende Überlegungen:
1. es gibt drei Arten von "falschen" Ortsnamen, z.B.
a) Koeln (Köln) -> mit Umlauten
b) Bad-Woerishofen (Bad Wörishofen) -> mit Leerzeichen und Umlauten
c) Neu-Guinea (Neu Guinea) -> nur mit Leerzeichen
2. diese "falschen" Ortsnamen in richtige Strings umwandeln. Dazu benütze ich die Funktion umlauten()
3. Um die Datenbank-Abfragen möglichst gering zu halten, wird überprüft ob sich der String überhaupt geändert hat. Zum Beispiel wir bei "Paris" der String nicht verändert, also ist auch keine Datenbank-Abfrage nötig.
4. Bekomme ich von der Datenbank einen Wert, dann nehme diesen als Argument.
Das ganze Prozedere muss ich einmal für die Länder und einmal für die Städte machen. Bei den Kontinenten gibt es glaub keine mit Umlaute ;-)
Hier der Code - ich wäre froh, wenn jemand gegenchecken würde, man kann bestimmt hier und da noch den Code vereinfachen - aber die Lösung funktioniert zumindest.
<?php
$continent = $args[0];
$country = $args[1];
$city = $args[2];
function umlauten($strarg) {
$b_array = array ("ae" => "ä", "ue" => "ü", "oe" => "ö", "ss" => "ß");
$arg_umlaute[0] = strtr($strarg, $b_array); //z.B. Koeln -> Köln
$arg_umlaute[1] = strtr($arg_umlaute[0], "-", " "); //z.B. Bad-Woerishofen -> Bad Wörishofen
$arg_umlaute[2] = strtr($strarg, "-", " "); //z.B. New-York -> New York
return $arg_umlaute;
}
// country umwandeln
$um_country = umlauten($country);
// Überprüfen, ob sich was am String verändert hat
$flagge = FALSE;
foreach ($um_country as $aktuell) {
if (!($aktuell == $country)) {
global $flagge;
$flagge = TRUE;
}
}
//wenn String sich verändert hat, dann DB-Anfrage
if ($flagge) {
$res = db_result(db_query("SELECT city FROM {locations}
WHERE continent = '%s' AND (country = '%s' OR country = '%s' OR country = '%s')",
$continent, $um_country[0], $um_country[1], $um_country[2]));
if ($res) {
$args[1] = $res;
$country = $res; //Vari aktualisieren für die city-DB-Abfrage
}
}
// city umwandeln
$um_city = umlauten($city);
// Überprüfen, ob sich was am String verändert hat
$flagge = FALSE;
foreach ($um_city as $aktuell) {
if (!($aktuell == $city)) {
global $flagge;
$flagge = TRUE;
}
}
//wenn String sich verändert hat, dann DB-Anfrage
if ($flagge) {
$res = db_result(db_query("SELECT state FROM {locations}
WHERE continent = '%s' AND country = '%s' AND (city = '%s' OR city = '%s' OR city = '%s')",
$continent, $country, $um_city[0], $um_city[1], $um_city[2]));
if ($res)
$args[2] = $res;
}
return $args;
?>
Wie schon gesagt, wäre schön wenn jemand den Code zur Optimierung durchschauen könnte. Danke an alle, die mir bis hierher geholfen haben!!