Search the FirstSpirit Knowledge Base
Ein freundliches Hallo an Alle,
gibt es eine Möglichkeit in FS eine Art Stapelverarbeitung über zBsp. Medienverzeichnis zu machen? Eine der Anforderung Lautet: Bildergalerie aus einem Verzeichnis zu erstellen. Angezeigt werden alle Bilder aus ausgewähltem Verzeichnis.
MfG Salesski
Wie Holger schon sagte sollte sowas aus Performancegründen nach Möglichkeit immer über Templatemittel also ohne Skript gelöst werden. Die Lösung von Holger funktioniert so nicht ganz, deshalb hier nochmal zusammengefasst:
Komponente im Formular
--------------------------------------
<CMS_INPUT_FILE name="st_folder" allowFolder="yes" hFill="no" useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Medienordner" description="Bitte einen Medienordner wählen"/>
</LANGINFOS>
</CMS_INPUT_FILE>
Templatecode im Html-Kanal
------------------------------------------
$CMS_SET(mediaClass, class("de.espirit.firstspirit.access.store.mediastore.Media"))$
$CMS_FOR(m, st_folder.getFolder().getChildren(mediaClass, false))$
$CMS_IF(m.getType() == m.PICTURE)$ $-- check against static type field --$
<img src="$CMS_REF(m)$"/><br/>
$CMS_END_IF$
$CMS_END_FOR$
Welche Version setzt Ihr ein?
Mit Version 4.2 gibt es da wohl einige tolle neue Features in diesem Bereich.
Wir haben aktuell noch 4.1 und haben uns ein Skript gebaut, dass so umgebaut werden könnte, dass es macht, wass Ihr braucht - allerdings ist das bei uns noch mehr dazugebaut. Ich habe mal versucht die zusätzlichen Teile auszubauen.
Unser Skript:
//!Beanshell
import java.util.Iterator;
import java.util.List;import de.espirit.firstspirit.access.GenerationScriptContext;
import de.espirit.firstspirit.access.editor.value.BinaryMedium;
import de.espirit.firstspirit.access.store.StoreElement;
import de.espirit.firstspirit.access.store.mediastore.Media;
import de.espirit.firstspirit.access.store.mediastore.MediaFolder;
import de.espirit.firstspirit.access.project.Resolution;
import de.espirit.firstspirit.access.store.mediastore.Picture;
import de.espirit.firstspirit.access.store.mediastore.PictureResolution;import de.espirit.firstspirit.generate.ScriptResultWrapper;
import de.espirit.firstspirit.access.store.PageParams;
import de.espirit.firstspirit.access.store.ContentProducer;
import de.espirit.firstspirit.generate.DefaultUrlCreator;
private static StringBuffer resultBuffer = new StringBuffer();try {
// retrieve MediaFolder from GUI
Object o = context.getProperty("folder");
MediaFolder mf = null;
if (o instanceof MediaFolder) { // is MediaFolder
mf = (MediaFolder) o;
}
if (mf == null) throw new IllegalArgumentException("Parameter is is not a valid Element from the Media-Store!");
// get resolution
String res = context.getProperty("resolution")+"";
// get language
lang = context.getLanguage();
// select all pictures and write references
List l = mf.getChildren(Media.class, true).toList();
for (Iterator iter = l.iterator(); iter.hasNext();) {
Media m = (Media) iter.next();
// only relevant for pictures
if (m.getType() == Media.PICTURE) {
resultBuffer.append("<img src=\"$CMS_REF(media:\"");
resultBuffer.append(m.getUid());
resultBuffer.append("\", resolution:\"").append(res);
resultBuffer.append("\")$");
resultBuffer.append("\" />");
}
}
result.setValue(resultBuffer.toString());
} catch (Exception e) {
context.logError("Failed to dummy-reference folder '" + context.getProperty("st_folder") + "' !");
context.logError("Message: " + e.getMessage());
}
Formular:
<CMS_MODULE>
<CMS_INPUT_FILE name="st_folder" allowFolder="yes" hFill="no" useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Medienordner" description="Bitte einen Medienordner wählen"/>
</LANGINFOS>
</CMS_INPUT_FILE><CMS_INPUT_COMBOBOX name="st_resolution" useLanguages="no">
<ENTRIES>
<ENTRY value="ORIGINAL">
<LANGINFOS>
<LANGINFO lang="*" label="ORIGINAL"/>
</LANGINFOS>
</ENTRY>
<ENTRY value="bild1">
<LANGINFOS>
<LANGINFO lang="*" label="Bild 1"/>
</LANGINFOS>
</ENTRY>
<ENTRY value=bild2">
<LANGINFOS>
<LANGINFO lang="*" label="Bild 2"/>
</LANGINFOS>
</ENTRY>
</ENTRIES>
<LANGINFOS>
<LANGINFO lang="*" label="Auflösung" description="Die Auflösung, in der alle Bilder des Medienordners veröffentlich werden sollen"/>
</LANGINFOS>
</CMS_INPUT_COMBOBOX></CMS_MODULE>
Ausgabe im Absatz:
$CMS_SET(set_media_sitemap)$
$CMS_RENDER(script:"mediasitemap",folder:st_folder,resolution:st_resolution)$
$CMS_END_SET$$CMS_VALUE(set_media_sitemap)$
In 4.1 habe iich das so gelöst:
CMS_INPUT_PICTURE Komponente, mit der ein Bild aus dem entsprechenden Ordner ausgewählt werden soll.
<CMS_INPUT_PICTURE name="pic" label="picture"/>
Im Quelltext dann alle Bilder des Ordners einfach ausgeben:
$CMS_FOR(pics,pic.medium.parent.getChildren(pic.medium.class))$
$CMS_IF(pics.type == pic.medium.type)$
<img src="$CMS_REF(pics)$"/><br>
$CMS_END_IF$
$CMS_END_FOR$
In der Version 4.2 würde ich wahrscheinlich FS_REFERENCE benutzen, um den Ordner auszuwählen. Allerdings muss man dann im Quellcode die Klasse für die Bilder übergeben.
$CMS_SET(mediaClass,class("de.espirit.firstspirit.access.store.mediastore.Picture"))$
Wie Holger schon sagte sollte sowas aus Performancegründen nach Möglichkeit immer über Templatemittel also ohne Skript gelöst werden. Die Lösung von Holger funktioniert so nicht ganz, deshalb hier nochmal zusammengefasst:
Komponente im Formular
--------------------------------------
<CMS_INPUT_FILE name="st_folder" allowFolder="yes" hFill="no" useLanguages="no">
<LANGINFOS>
<LANGINFO lang="*" label="Medienordner" description="Bitte einen Medienordner wählen"/>
</LANGINFOS>
</CMS_INPUT_FILE>
Templatecode im Html-Kanal
------------------------------------------
$CMS_SET(mediaClass, class("de.espirit.firstspirit.access.store.mediastore.Media"))$
$CMS_FOR(m, st_folder.getFolder().getChildren(mediaClass, false))$
$CMS_IF(m.getType() == m.PICTURE)$ $-- check against static type field --$
<img src="$CMS_REF(m)$"/><br/>
$CMS_END_IF$
$CMS_END_FOR$
Hallo Thomas,
die Skriptbasierte Lösung funktioniert natürlich, so wie von dir beschrieben. Der Nachteil ist, dass durch das Starten des Skriptes ein, in diesem Fall unnötiger, Performanceverlust einhergeht.
Desweiteren fällt mir an dem Skript folgende Zeile auf:
// select all pictures and write references
List l = mf.getChildren(Media.class, true).toList();
Hier werden alle Medienelemente des Ordners rekursiv geholt. Problematisch ist hier, dass diese Elemente einer Liste zugewiesen werden. Die Elemente sind also komplett im Speicher. Sowas sollte man möglichst vermeiden.
Sinnvollerwäre an dieser Stelle direkt mit dem Listable zu arbeiten, welches von der Methode #getChildren() zurückgeliefert wird.
// select all pictures and write references
;
Listable listable = mf.getChildren(Media.class, true)
Hier muss man allerdings unterscheiden, ob man mit Beanshell (Skript) arbeitet oder in Java.
=== Javacode ===
// da Listable von java.lang.Iterable erbt kann hier direkt iteriert werden
for (Media m : listable) {
// ....
// Beanshell kann hingegen nicht über ein Iterable iterieren
}
=== Beanshell ===
iter = listable.iterator();
while(iter.hasNext()) {
m = iter.next();// ....
}
Entscheidend ist hierbei, dass bei den vorgenannten Iterationen nicht alle Elemente im Speicher vorgehalten werden.
$CMS_SET(mediaClass,class("de.espirit.firstspirit.access.store.mediastore.Picture"))$
Das funktioniert so nur, wenn auch rekursiv iteriert wird.
Es sollte eher der Medientyp verwendet werden und dann gegen den Typ geprüft werden, wie oben beschrieben.
$CMS_SET(mediaClass, class("de.espirit.firstspirit.access.store.mediastore.Media"))$
vielen Dank für die Hinweise - ich schau mir das in einer ruhigen Minute an - allerdings ist unser Code etwas komplexer als oben gepostet - ich habe da schon einiges weggelassen (deshalb sind im oberen Teil auch noch mehr Klassen includiert als unten verwendet werden.
Aber genauso wünsche ich mir die Community - ich denke, dass davon Hersteller und Kunden profitieren ...
if (m.getType() == Media.PICTURE) {
resultBuffer.append("<img src=\"$CMS_REF(media:\"");
resultBuffer.append(m.getUid());
resultBuffer.append("\", resolution:\"").append(res);
resultBuffer.append("\")$");
resultBuffer.append("\" />");
}
ich bräuchte nur noch den Text aus der Beschreibung der BilderresultBuffer.append(
m.getComment()); hat leider nicht geholfen.
Ansonsten war der Script sehr hilfreich. Danke!
resultBuffer.append(
m.getComment()); hat leider nicht geholfen.
ich bräuchte nur noch den Text aus der Beschreibung der BilderDie Beschreibung erhalten Sie über #getDescription()
$CMS_FOR(m, st_folder.getFolder().getChildren(mediaClass, false))$
$CMS_IF(m.getType() == m.PICTURE)$ $-- check against static type field --$
<img src="$CMS_REF(m)$"/><br/>$CMS_VALUE(m.picture(#global.language).description)$
$CMS_END_IF$
$CMS_END_FOR$
Gibt es fachliche Gründe, warum Sie sich für die Skriptlösung entschieden haben und nicht für die templatebasierte ?
Vilen Dank,
im Zusammenhang mit dem Script was ich gepostet habe, hat das hier zum erwünschtem Ergebnis geführt:
lang = context.getLanguage();
resultBuffer.append(m.getPicture(lang).getDescription());