Wer ein Portal entwickelt, benötigt Test-Content. Drupal stellt hierfür im Rahmen seines Devel-Moduls das leistungsfähige Sub-Modul Devel Generate zur Verfügung.
Damit lassen sich Lore Ipsum-Texte, Random-Bilder (s. Bild links), Lore Ipsum-Taxonomien sowie Inhalte für alle Felder für alle Content-Typen erzeugen.
Die Flexibilität dieses Moduls reicht allerdings nicht aus für anspruchsvollere Konfigurationen und Entwicklungen. Dafür sind programmtechnische Eingriffe erforderlich.
Das Standard-Modul ist sehr leistungsfähig und berücksichtigt alle möglichen Beziehungen und Einstellmöglichkeiten von Feldern.
Allerdings ist das Ergebnis häufig nicht realistisch genug für Design-Entscheidungen während der Entwicklung.
- Z.B. möchte man vielleicht für ein Preis-Feld den Werte-Bereich auf Werte zwischen 100 und 1500 Euro einschränken.
- Oder man möchte, dass Devel Generate für eine Taxonomie nicht einen beliebigen zufällig ausgewählten Wert einsetzt, sondern als Ausgangspunkt den für den Content-Typ jeweils eingestellen Default-Wert.
- Oder man möchte ganz einfach ein ansprechendes realistisches Bild für ein Image-Feld verwenden. Die Entwicklung macht einfach mehr Spaß, wenn man in der Kategorie "Katzen" auch zufällig ausgewählte Katzenbilder findet und nicht irgendeine abstrakte Zufallsgrafik.
Das letztgenannte Problem wird leider nur zum Teil durch das spezielle Modul Devel Image Provider gelöst, welches die von Devel erzeugen abstrakten Computergrafiken ersetzt durch realistische Bilder, die von auswählbaren Web-Services wie Flickholdr geladen werden. Es gibt aber bei diesem Modul keine Möglichkeit, solche Bilder abhängig von Kategorien, wie z.B. "Pets" oder "Real Estate" zu laden.
Hier hilft offenbar nur, selbst Hand anzulegen und das Devel-Modul zu modifizieren oder ein eigenes Modul zu entwickeln.
Der erste Weg erscheint allerdings nach näherer Analyse unpraktisch, da das Devel Generate-Modul keine geeigneten Hooks zur Verfügung stellt, um in den Generierungsprozess einzugreifen.
Stattdessen empfiehlt sich eine Strategie, den zufällig generierten Content vor der Speicherung abzugreifen und entsprechend den eigenen Vorstellungen zu modifizieren.
Dies ermöglich der Hook hook_node_presave. Die grundsätzliche Vorgehensweise dafür habe ich hier gefunden.
Im folgenden Code-Snippet habe ich die drei oben beschriebenen Fälle eingebaut, da diese in der Praxis häufig vorkommen.
/** * Change content of a node before the node is saved to the database. * Act on a node being inserted or updated. * (A modified version of http://www.wunderkraut.com/blog/generating-realistic-test-content/2011-03-07) * * @param $node * A node before saving * * @return void * */ function mymodule_node_presave($node) { // for content types beginning with 'my_' ... if ((strpos($node->type, 'my_') == 0) && isset($node->devel_generate)) { // Set field category from the random generated to the default category $field = field_info_field('field_my_categories'); $instance = field_info_instance('node', 'field_my_categories', $node->type); $defvalue = field_get_default_value('node', $node, $field, $instance, $node->language); $node->field_my_categories["und"][0]["tid"] = (int)$defvalue[0]["tid"]; // Substitute the generated random value for a price range $node->field_price["und"][0]["value"] = mt_rand(100, 1500); // Replace the computer generated picture by one in a categorized file folder $images = field_get_items('node', $node, 'field_my_market_image'); foreach ($images as $delta => $image) { // Pick one sample image randomly. $source = drupal_get_path('module', 'mymodule') . '/images/'.$node->type . '/' . rand(0, 9) . '.jpg'; if (file_exists($source)) { // Load the reference to the original from the database. $file = file_load($image['fid']); // Overwrite the original image with a copy of our sample image. $destination = $file->uri; $path = file_unmanaged_copy($source, $destination, FILE_EXISTS_REPLACE); } } } }
Dieses Snippet ist ein guter Ausgangspunkt für die automatische Generierung von realistischen Test-Inhalten.
Es lohnt sich vielleicht, dafür direkt zu Beginn eines Projekts ein eigenes Modul anzulegen, das zusammen mit dem Fortschreiten des Projekts laufend erweitert werden kann. Später im Produktionssystem kann man ein solches Modul dann zusammen mit den devel-Modulen einfach abschalten.