Bildergallerie sortieren

Bicko

Erfahrenes Mitglied
Hi,

ich bin wirklich am verzweifeln und finde einfach keine Lösung. Ich habe eine kleine Gallerie gebastelt. Die Daten werden aus einer DB ausgelsen und in einem Array gespeichert. Dieses lese ich dann aus mit einer Foreach Schleife. Hier der Code:

PHP:
echo '<div id="gallery">';
$counter=0;
foreach ($ImageData as $ImageValue)
{
  if (file_exists($ImageFolder.$ImageValue['ImgNewName'])) 
  {
      if( $tmp != $ImageValue['ImageSubcategory'] ) 
      {
        echo '<h5>'.$ImageValue['ImageSubcategory'].'</h5>';
       $tmp = $ImageValue['ImageSubcategory'];
      }
      echo '<div><img src="'.$ImageFolder.$ImageValue['ImgNewName'].'"
 width="'.$ImageValue['ImgNewWidth'].'"  />';
    echo '<p class="caption">'.$ImageValue['ImageCaption'].'</p></div>';
   }
}
echo '</div>';

Nun habe ich aber ein Problem. Es sollen jeweils 4 Bilder nebeneinander, die zur einer Kategorie gehören, der Caption Text unter das jeweilige Bild.

Es kann also sein das es in einer kategorie nur 1 Bild gibt in der nächsten vielleicht 5.

kategorie 1
Bild 1 Bild 2

Kategorie2
Bild 1

Kategorie 3
Bild 1 Bild 2 Bild 3 Bild 4
Bild 5 Bild 5

Mein Css sieht momentan so aus:

PHP:
#gallery div{
	background:url(../images/rahmen.jpg);
	background-repeat:no-repeat;
	height:125px;
	display:block;
	width:125px;	
}

#gallery img{
	padding-top:5px;
	padding-left:13px;
}

#gallery p.caption{
	font-size:10px;
	color:#999999;
	font-weight:bold;
	text-align:center;
}

Das klappt aber hinten und vorne nicht. Die Bilder sind untereinander und wenn ich bei #gallery div ein float:left reinschreibe werden die schräg untereinander angeordnet die Kategorien aber gemischt. Ich habe momentan echt keinen Ansatz, wie ich das lösen kann. Ich würde mich riesig freuen, wenn mir jemand einen Tip geben könnte.

Vielen Dank im Voraus.

Gruß Bicko
 
Mir scheint dass dein Datenbankmodell noch ein bisschen an Überarbeitung benötigt.
Kurze Erklärung was ich meine:
Kategorien sollten in einer eigenen Tabelle angelegt werden und per ForeignKey den Bildern zugewiesen.
Bei der Ausgabe durchläufst du dann die ganzen Kategorien welche du über einen Select ausliest.
Und innerhalb dieser Schleife machst du eine Abfrage welche dir die Bilder mit der Aktuellen Kategorien-ID zurückgibt.
----------------------------
Aber es geht natürlich auch mit dem aktuellen Modell. Das Einzige was du beachten musst ist dass du beim SELECT Query nach der ImageSubcategory sortierst damit du auch die Bilder der aktuellen Kategorie nach der Reihe bekommst. (SELECT * FROM `Images` ORDER BY `ImageSubcategory`;)

Die Idee ist folgende: Du gibst den Kategoriennamen aus sofern der nicht mit der Vorhergehenden übereinstimmt. So wie du es bisher hast (fast). Nur musst du bei jedem Bild in die $tmp deinen Kategoriennamen speichern sodass du weißt ob sich der Kategorienname geändert hat.
Für die 4 Bilder in 1 Zeile machst du einfach Folgendes: Du erstellst einen Bildzähler welcher speichert wieviele Bilder ausgegeben wurden. Dieser Zähler wird bei jedem Schleifendurchgang während der Ausgabe hochgezählt. Sobald 4 Bilder erreicht wurden kannst du dann einfach einen Zeilenumbruch ausgeben (<br />). Dann noch den Zähler wieder auf 0 stellen um die Zählung neu zu starten.

Das einzige Problem ist jedoch noch dass DIV-Container standardmäßig nicht nebeneinander angezeigt werden. Dazu müsstest du noch im CSS im Div-Selector das Attribut float:left hinzufügen. Dann werden sie nebeneinander angezeigt.

Ausgecodet sieht das ganze dann so aus (leider nicht getestet da ich gerade neu aufgesetzt habe und noch kein Webserver laufen habe und da es schon 5 Uhr ist; Aber morgen :D)
PHP:
<?php
$imgCount = 0; // Bilderzähler: 0 Bilder am Anfang ausgegeben
$lastCat = ""; // Beinhaltet die Vorhergehende Kategorie
$columns = 4; // Anzahl der Spalten der Bilder


// Gallery Starten
echo '<div id="gallery">';
// Alle Bilder durchlaufen
foreach ($ImageData as $ImageValue) 
{
  // Nur Ausgeben wenn die Datei existiert
  if (file_exists($ImageFolder.$ImageValue['ImgNewName'])) 
  {
    // Wenn eine neue Kategorie beginnt (d.H. vorherige Kategorie entspricht nicht der Aktuellen)
    if( $lastCat != $ImageValue['ImageSubcategory'] ) 
    {  
      // Überschrift ausgeben
      echo '<h5>'.$ImageValue['ImageSubcategory'].'</h5>';
    }
    // Bild ausgeben 
    echo '<div><img src="'.$ImageFolder.$ImageValue['ImgNewName'].'" width="'.$ImageValue['ImgNewWidth'].'" />';
    echo '<p class="caption">'.$ImageValue['ImageCaption'].'</p></div>';
    // Zähler hochzählen (+1 Bild)
    $imgCount++;
    // Wenn 4 Bilder ausgegeben wurden. 
    if($imgCount == $columns)
    {
      // Ein Zeilenausbruch  ausgeben
      echo '<br />';
      // Und Zähler zurücksetzen 
      $imgCount = 0;
    }
    // Bei jedem Bild wird die Kategorie gespeichert
    $lastCat = $ImageValue['ImageSubcategory'];
   }
}
// Gallerie beenden
echo '</div>';
?>

CSS:
#gallery div{
    background:url(../images/rahmen.jpg);
    background-repeat:no-repeat;
    height:125px;
    display:block;
    float:left;
    width:125px;    
}
...

Ich hoffe es bringt dich weiter :)
 
@Danielku15,

Vielen, vielen Dank. Da war ich wirklich dicht davor, aber manchmal sieht man wirklich nichts mehr. Übrigens benutze ich mehrere Tabellen (Normalisieren :), die ich aber per Join zusammengefügt habe.

Es lag nur an dem Order BY, an das ich nicht mehr gedacht habe. Jetzt ist es wirklich nur noch ein kleines CSS Problem. Die Überschrift bleibt momentan noch auf der Höhe des vorherigen Bildes. Sprich der eine <br /> reicht nicht. Nun möchte ich aber auch keine 100 br's setzen. Wie kann man das dann am besten machen?

Vielen dank nochmal. Gruss Bicko
 
Wenn du keine Breaks sondern lieber Absätze mit <p> machst kannst du ja das <br /> durch </p> ersetzen und am Anfang der Foreach Schleife noch eine Abfrage einbauen ob der Zähler 0 ist und dann ein <p> ausgeben. Somit erhälst du am Anfang der Zeile (Zähler 0) ein <p> und am Ende (bei Zähler == $Columns) ein </p>.

Zudem könnest du nach der Kategorien Ausgabe ein weiteren <p> starten um die ganze Kategorie zu gruppieren. Was du dir dann noch überlegen musst ist wie du diesen schließt. Du könntest ihn vor dem Kategorienname schließen sofern es nicht die erste Kategorie ist.

So in der Art:
PHP:
<?php
$imgCount = 0; // Bilderzähler: 0 Bilder am Anfang ausgegeben
$lastCat = ""; // Beinhaltet die Vorhergehende Kategorie
$columns = 4; // Anzahl der Spalten der Bilder
$firstCat = true; // Um die erste Kategorie zu identifizieren

// Gallery Starten
echo '<div id="gallery">';
// Alle Bilder durchlaufen
foreach ($ImageData as $ImageValue) 
{
  // Nur Ausgeben wenn die Datei existiert
  if (file_exists($ImageFolder.$ImageValue['ImgNewName'])) 
  {
    // Wenn eine neue Kategorie beginnt (d.H. vorherige Kategorie entspricht nicht der Aktuellen)
    if( $lastCat != $ImageValue['ImageSubcategory'] ) 
    {  
      if($firstCat) // Erste Kategorie die Ausgegeben wird?
      {
        // Keine Ausgabe und Umschalten
        $firstCat = false;
      }
      else // Alle Folgenden Kategorien
      {
        // Kategoriengruppe Beenden
        echo '</p>';
      }
      // Kategoriengruppe starten
      echo '<p>';
      // Überschrift ausgeben
      echo '<h5>'.$ImageValue['ImageSubcategory'].'</h5>';
      
    }
    // Erstes Bild der Zeile?
    if($imgCount == 0)
    {
        // Absatz beginnen. 
        echo '<p>';
    }
    
    // Bild ausgeben 
    echo '<div><img src="'.$ImageFolder.$ImageValue['ImgNewName'].'" width="'.$ImageValue['ImgNewWidth'].'" />';
    echo '<p class="caption">'.$ImageValue['ImageCaption'].'</p></div>';
    // Zähler hochzählen (+1 Bild)
    $imgCount++;
    // Wenn 4 Bilder ausgegeben wurden. 
    if($imgCount == $columns)
    {
      // Zeile Beenden
      echo '</p>';
      // Und Zähler zurücksetzen 
      $imgCount = 0;
    }
    // Bei jedem Bild wird die Kategorie gespeichert
    $lastCat = $ImageValue['ImageSubcategory'];
   }
}
// Gallerie beenden
echo '</div>';
?>
 
Zuletzt bearbeitet:
@Danielku15,

danke für den Vorschlag, aber leider hat sich rein gar nicht geändert. Die Bilder sind immer noch nebeneinader, obwohl eine neue Kategorie gestartet wurde. Es wurde gerade mal ein break eingefügt, den nun durhc das p kommt. Es fängt jedoch nicht unterhalb der ersten Kategorie an.

Wie kann man das denn nur am Einfachsten lösen? Im www habe ich Tabellen Lösungen gefunden, aber das will ich auf keinem Fall. Würde es mit einer Liste leichter sein?
Es muss doch eine saubere und elegant Lösung geben...

Noch jemand einen Tip wo mein Denkfehler liegt? Vielen dank im Voraus.

gruss Bicko
 
Die saubere, elegante Lösung wäre mit Tabellen über Templates. Denn du probierst ja im Moment genau eine Tabelle zu immitieren. Du könntest natürlich auch einfach alle Divs nebeneinander Plazieren und in den gallery-div auf der Breite so begrenzen dass nur 4 Bilder Platz haben.
Wenn mit der Plazierung was nicht ganz stimmt mach mal von Hand 1-2 Kategorien so wie sie aussehen sollen und splitte das ganze dann so auf dass es dynamisch ausgegeben wird.
 
Zurück