tag:www.stefanwienert.net,2008:/drupal Drupal - Stefan Wienert's Blog 2012-01-11T18:42:14Z Enki Stefan Wienert stwienert@gmail.com tag:www.stefanwienert.net,2008:Post/75 2012-01-11T16:42:00Z 2012-01-11T18:42:14Z Effektive Corporate Website mit Drupal und Installationsprofilen <p>Um eine typische Unternehmensseite halbwegs modern und effektiv umzusetzen, eignet sich das relativ neue Drupal 7 ideal.</p> <p>Dazu gibt es einen super-effektiven, fertigen Baukasten (Installationsprofil) bei Github (https://github.com/juampy72/corporative-site), der allerhand coole Module mitbringt und gescheit konfiguriert: File-Upload, <span class="caps">WYSIWYG</span>-Editor, lesbare URLs, sitemap, robots.txt</p> <p>Hier ein Mini-Guide um Drupal 7 mit diesem Profil mit einer deutschen Übersetzung zu installieren an einem Beispiel-Plesk/Debian System:<br /> <pre><code> cd httpdocs git clone git://github.com/juampy72/corporative-site.git . chown www-data sites/default/ -R</p> <p>mkdir -p profiles/corporative_site/translations<br /> cd profiles/corporative_site/translations<br /> wget http://ftp.drupal.org/files/translations/7.x/drupal/drupal-7.10.de.po<br /> </code></pre></p> <p>Danach die Seite im Browser öffnen und den Installationsanweisungen folgen.</p> <p>Ein schönes Theme für Corporate Seite ist, wie ich finde <a href="http://drupal.org/project/corporateclean">Corporate-Clean</a>.</p> tag:www.stefanwienert.net,2008:Post/53 2010-09-03T06:40:00Z 2010-09-03T08:40:21Z Drupal Modulentwicklung - I - Einführung und Hello World <p>Beruflich habe ich recht viel mit Drupal zu tun, einem in <span class="caps">PHP</span> geschriebenem <span class="caps">CMS</span>. Das Plugin-System, Module genannt, ist recht umfangreich und bietet vielfältige Möglichkeiten, fast jede Stelle des CMS&#8217; anzupassen, ohne wirklich am Kerncode rumzuhacken.</p> <p>Das ganze ist recht durchdacht, und bei weitem besser als nacktes <span class="caps">PHP</span>. Desweiteren bin ich kein großer &#8220;Fan&#8221; von den beiden Modulen &#8220;Views&#8221; und &#8220;<span class="caps">CCK</span>&#8221;, die sehr oft verwendet werden, um Modelle und <span class="caps">SQL</span> Statements nachzubilden. Ich bevorzuge aber Code, und nicht das Zusammenklicken dessen.</p> <p>Voraussetzung für das Tutorial:</p> <ul> <li>installiertes Drupal 6</li> <li><span class="caps">PHP</span>/<span class="caps">SQL</span> Erfahrungen</li> </ul> <h3>Hello World Modul</h3> <p>Drupal bietet zwei Ordner an, in die wir unsere Module packen können: ./modules und ./sites/all/modules. Der Konvention nach, sollten selbstgeschriebene Module in den letzteren, beides arbeitet aber korrekt.</p> <p>In einen der beiden Ordner legen wir nun einen neuen Ordner an:</p> <p>./modules/helloworld bzw. ./sites/all/modules/helloworld</p> <p>In der Regel heißt der Ordner des Moduls so, wie das Modul selbst. Das muss aber nicht so sein. Auch können noch beliebige weitere Unterordner vorher folgen, um z.B. alle Module einer gewissen Funktionalität zu bündeln.</p> <p>Ein Drupalmodul hat mindestens 2 &#8220;magische&#8221; Dateien, also Dateien, die per Definition eine besondere Rolle haben.</p> <p>./helloworld/helloworld.info<br /> ./helloworld/helloworld.module</p> <h4>helloworld.info</h4> <p>./helloworld/helloworld.info ist nur eine Datei, wo Metainformationen über das Modul stehen, und woraus die Informationen für die Modulseite entnommen werden. Der Aufbau ist vorgegeben und recht kurz:</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt>3<tt> </tt>4<tt> </tt>5<tt> </tt>6<tt> </tt>7<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">; $Id$<tt> </tt>name = Hello World Modul<tt> </tt>description = ...<tt> </tt>package = StWienert<tt> </tt>version = 1.0<tt> </tt>core = 6.x<tt> </tt>dependencies = user<tt> </tt></pre></td> </tr></table> <p>Damit definiere ich, dass mein Modul vom Modul user abhängt, also nicht ohne dieses aktiviert werden kann, und in der &#8220;Package&#8221; StWienert, d.h. einer gesonderten Gruppierung &#8220;StWienert&#8221;, in der Modulübersicht zu finden ist.</p> <h4>helloworld.module</h4> <p>Dies ist eine <span class="caps">PHP</span>-Datei, die erst aufgerufen wird, falls unser Modul aktiviert ist. Hier der Code für ein Hello world:</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt>3<tt> </tt>4<tt> </tt>5<tt> </tt>6<tt> </tt>7<tt> </tt>8<tt> </tt>9<tt> </tt><strong>10</strong><tt> </tt>11<tt> </tt>12<tt> </tt>13<tt> </tt>14<tt> </tt>15<tt> </tt>16<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="idl">&lt;?php</span><tt> </tt><span class="r">function</span> <span class="fu">helloworld_menu</span>() {<tt> </tt> <span class="lv">$items</span> = <span class="pd">array</span>();<tt> </tt> <span class="lv">$items</span>[<span class="s"><span class="dl">'</span><span class="k">test/helloworld</span><span class="dl">'</span></span>] = <span class="pd">array</span>(<tt> </tt> <span class="s"><span class="dl">'</span><span class="k">title</span><span class="dl">'</span></span> =&gt; <span class="s"><span class="dl">'</span><span class="k">Hello-World Site</span><span class="dl">'</span></span>,<tt> </tt> <span class="s"><span class="dl">'</span><span class="k">page callback</span><span class="dl">'</span></span> =&gt; <span class="s"><span class="dl">'</span><span class="k">_helloworld_page</span><span class="dl">'</span></span>,<tt> </tt> <span class="s"><span class="dl">'</span><span class="k">access arguments</span><span class="dl">'</span></span> =&gt; <span class="pd">array</span>(<span class="s"><span class="dl">'</span><span class="k">access content</span><span class="dl">'</span></span>),<tt> </tt> <span class="s"><span class="dl">'</span><span class="k">type</span><span class="dl">'</span></span> =&gt; <span class="co">MENU_CALLBACK</span>,<tt> </tt> );<tt> </tt> <span class="r">return</span> <span class="lv">$items</span>;<tt> </tt>}<tt> </tt><tt> </tt><span class="r">function</span> <span class="fu">_helloworld_page</span>() {<tt> </tt> <span class="r">return</span> <span class="s"><span class="dl">&quot;</span><span class="k">hello World</span><span class="dl">&quot;</span></span>;<tt> </tt>}<tt> </tt><span class="c"># kein schlie?endes </span><span class="idl">?&gt;</span> notwendig, da die Datei inkludiert wird<tt> </tt></pre></td> </tr></table> <p>Nun können wird das Modul aktivieren, und die Seite &#8220;example.com/test/helloworld&#8221; aufrufen, und sollten unser Hello World sehen.</p> <p>Drupal basiert auf einem <b>Callbacksystem</b>. Funktionen, mit einem genau spezifizierten Namen, werden zu bestimmten Zeitpunkten aufgerufen und können Einfluss nehmen. Diese besonderen Funktionen werden <b>&#8220;Hooks&#8221;</b> genannt, <a href="http://api.drupal.org/api/group/hooks/6">wovon es eine ganze Menge gibt.</a> <br /> Hier verwenden wir den sogenannten <a href="http://api.drupal.org/api/function/hook_menu">hook_menu</a>. Anstelle von &#8220;hook&#8221; müssen wir den (internen) Namen des Moduls einsetzen, also denselben Namen, den unsere Dateien .info und .module führen.</p> <p>Ein paar der interessanteren Hook-Funktionen werde ich in einem folgenden Blogpost vorstellen, ansonsten ist ein wenig Stöbern in der Übersicht angebracht.</p> <h3>Addendum</h3> <h4>Must-have-Module</h4> <p>Hier noch die wesentlichen Basis-Developer-Module, die ich nicht mehr missen möchte. Was hätte ich an Zeit gespart, hätte ich gleich das alles gewusst :)</p> <ul> <li><a href="http://drupal.org/project/admin_menu">admin_menu</a> Fügt ein JS Menü am oberen Bildrand, mit denen man sehr schnell an den benötigten Funktionen ist, und sich auf Dauer Fantastillarden an Klicks erspart. Ausserdem gibt es einen &#8220;Cache leeren&#8221; Button unter dem ersten Menüpunkt. Dieser ist wichtig, um z.B. den hook_menu unseres Moduls nach einer Änderung noch einmal aufgerufen wird. Sonst wird u.a. die Menüinformation gecacht.</li> <li><a href="http://drupal.org/project/devel">devel</a> Fügt zwei für mich wesentliche Dinge ein; eine Funktion &#8220;dpm($variable)&#8221;, die wie das print_r von <span class="caps">PHP</span> funktioniert, aber das ganze wesentlich übersichtlicher. Zweiteres einen Error-Backtrace. Also statt &#8220;Whitescreen of Death&#8221; gibt es detaillierte Fehlerinformationen, neben einer Fehlermeldung und exakter Ort des Auftretens auch alle Variablen des aktuellen Kontextes. Quasi ein Debugger für Arme. Das Modul hat noch viele Features mehr, ein Blick lohnt.</li> <li>drush Drupal-Shell. Dies ist kein Drupalmodul, sondern ein externes Programm, das eine neue Schnittstelle zu Drupal eröffnet, nämlich die Kommandozeile. Dies kann natürlich nur installiert werden, wenn man Shellzugriff auf seinen Server hat. Hier ein paar Leckerbissen:</li> </ul><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt>3<tt> </tt>4<tt> </tt>5<tt> </tt>6<tt> </tt>7<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">drush dl admin_menu &amp;&amp; drush en admin_menu<tt> </tt><span class="c"># Ladet das Modul admin_menu herunter, entpackt es </span><tt> </tt><span class="c"># nach sites/all/modules, dann wird das gleich aktiviert (enabled)</span><tt> </tt>drush cc<tt> </tt><span class="c"># leert den Cache</span><tt> </tt>drush eval <span class="s"><span class="dl">&quot;</span><span class="k">echo 'hello world'</span><span class="dl">&quot;</span></span><tt> </tt><span class="c"># Führt beliebigen PHP Code im Kontext des Drupals aus</span><tt> </tt></pre></td> </tr></table> <h4><span class="caps">CRE</span></h4> <p>Der Chaosradio-Radio-Express Podcast hat eine Sendung zum Thema Drupal. Hierbei geht es aber nicht um die Modulentwicklung, sondern um das Ökosystem allgemein.<br /> Interessant ist das Fazit von Tim Pritlove: &#8220;Es ist ja nicht so, dass es [Drupal a.d.R.] sich anbiedern würde&#8221;. Ja das stimmt, Drupal haut nicht vom Hocker, und gerade die Features der z.B. DatenbankAPI nicht gerade auf Höhe der Zeit. Aber es ist was grundsolides und sehr flexibles.</p> tag:www.stefanwienert.net,2008:Post/29 2010-01-20T17:17:00Z 2010-01-20T18:17:51Z Aktuelle Projekte und Ideen <p>Wenn ich zur Zeit während meines Praktikums etwas Zeit habe, arbeite ich an ein paar Hobbyprojekten, die mir so in letzter so eingefallen sind:</p> <ul> <li>Ein (hübsches) (openSource) <strong><acronym title="Dokumenten Management System"><span class="caps">DMS</span></acronym></strong> basierend auf Rails, welches <strong>doc, pdf, odf, text</strong> archiviert, taggt und indexiert, um die Dokumente leichter wiederzufinden <ul> <li>mit Paperclip, Ferret als Indexierungsdienst, Verwendung von pdftotext, antiword, odf2text und eventuell tesseract zum <span class="caps">OCR</span> (auch für Bilder und pdfs), rspec <acronym title="Behavior Driven Development"><span class="caps">BDD</span></acronym> Tests für die Modelle</li> </ul></li> <li>Einen &#8220;Bot&#8221;, der die eigene Website abgrast um interne <strong>Linkverbindungen als Graphen</strong> darzustellen, um so lange Wege zu finden und zu eliminieren (Webdesignregel: Redundanz und kurze Wege) <ul> <li>Ruby mit mechanize oder evtl. auch einfach &#8220;wget -spider&#8221; nehmen, graphviz</li> </ul></li> <li><strong>Drupal Scaffold</strong> Ein Ruby Skript, welches mir, ähnlich dem scaffold von Rails, ein Datenmodell in ein (MySQL) Schema gießt, und auch gleich einen (einfachen) Adminsetter dazu liefert (eine Seite unter admin/settings/%name mit der Option, ein neues Objekt anzulegen und alte anzuschauen.</li> </ul> tag:www.stefanwienert.net,2008:Post/8 2009-10-31T17:16:00Z 2009-10-31T18:16:51Z Gedit Addon für Drupal + Issue [SOLVED] <p>Wer viel mit drupal arbeitet und gerne gedit nehmen möchte, sollte sich mal diese Snippet und Mimitype Collection <a href="http://github.com/mavimo/gedit-drupal">auf github anschauen</a>.</p> <p>Einfach z.B. &#8220;hook&#8221; eingeben, &lt;tab&gt; und schon hat man eine Auswahl aller hooks, welche nach Auswahl gleich eine ordentliche Portion Quelltext mitbringen &#8211; <span class="caps">UND</span> &#8211; gleich den Modulnamen beinhalten (abgeleitet aus dem Datennamen). <br /> Fazit: Massig Zeit gespart :)</p> <p>Wermutstropfen: Seit dem Upgrade von <a href="http://ikhaya.ubuntuusers.de/2009/10/29/ubuntu-9-10-karmic-koala-ist-erschienen/">Ubuntu Jaunty auf Karmic Koala</a> geht das mit dem Modulnamen nicht mehr. Ich Habe beim Autor auf github mal einen <a href="http://github.com/mavimo/gedit-drupal/issues#issue/6">Bugreport</a> verfasst, in der Zwischenzeit kann man folgende Shellkommandos ausführen um die Snippets dennoch lauffähig zu bekommen. (Ich gehe davon aus, dass die Snippets bereits importiert sind, ansonsten das sed Kommando auf die &#8220;drupal.xml&#8221; im git-Verzeichnis ausführen)</p><table class="CodeRay"><tr> <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt> </tt>2<tt> </tt></pre></td> <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">cd ~/.gnome2/gedit/snippets/<tt> </tt>sed -i 's/\$GEDIT_BASENAME/\$GEDIT_CURRENT_DOCUMENT_NAME/g' drupal.xml<tt> </tt></pre></td> </tr></table>