Artikel-Migration von CMS nach WordPress – Teil 2

Zum Anfang der Serie Artikel-Migration von CMS nach WordPress – Teil 1

In der Tabelle wp_terms werden in WordPress die Kategorien gespeichert
In der Tabelle wp_terms werden in WordPress die Kategorien gespeichert

Schritt 3: Kategorien anlegen
Wenn das bisherige CMS mit Kategorien gearbeitet hat, was sinnvoll ist, sollten diese im Dashboard unter dem Punkt „Artikel/Kategorien“ angelegt werden (siehe auch „WordPress: mehrdimensionale Kategorien„). Bei der Anlage der Kategorie ist darauf zu achten, dass im Feld „Slug“ die Kategorie URL-verträglich eingegeben wird. So sollte beispielsweise aus „Meine Tipps“ „meine-tipps“ und aus „Kuriositäten“ ein „kuriositaeten“ werden.
In der Tabelle „wp_terms“ speichert WordPress diese Daten. Wir werden diese später noch benötigen.

 


Schritt 4: Benutzer anlegen
Es ist darauf zu achten, dass nun auch alle Benutzer, die auf dem alten CMS Artikel verfasst haben, auf der neuen WordPress-Installation angelegt wurden. Sind Artikel im Altsystem von Benutzer verfasst worden, die inzwischen nicht mehr tätig sind, sollten diese Benutzer ebenfalls angelegt werden, damit der Artikel samt Benutzerdaten migriert werden kann. Andernfalls muss man sich überlegen, wie mit den Artikeln umgegangen werden soll. Die Benutzerdaten speichert WordPress in der Tabelle „wp_user“.

Schritt 5: Datenbank sichern
Wenn alle Benutzer angelegt wurden, alle Kategorien angelegt sind und alle Einstellungen getätigt sind, ist es Zeit, die Datenbank zu sichern. Via „phpmyadmin“ kann beispielsweise ein Export erfolgen.

Schritt 6: Alte CMS-Datei analysieren
Es gilt zu analysieren, wie das bisherige CMS mit seinen Daten umgegangen ist. Es stellen sich die Fragen, in welchem Feld die bisherige Kategorie zum Artikel angegeben ist, wie der Benutzer gekennzeichnet ist, und ob alle Felder in einer Tabelle vorhanden sind. Im folgenden Beispiel gehen wir davon aus, dass alle Daten in der Tabelle „artikel“ enthalten sind. Ein Datensatz kennzeichnet einen Artikel. Über Normalisierung sind die Beziehungen zum Benutzer und zur Kategorie verfügbar.

Weiter geht es im nächsten Teil unserer kleinen Serie: Artikel-Migration von CMS nach WordPress – Teil 3

Artikel-Migration von CMS nach WordPress – Teil 1

Die Gründe, auf WordPress als Content Management System (CMS) umzusteigen, sind vielfältig. Gerade im Netz sind viele Meinungen über die verschiedenen Content Management Systeme nachzulesen. Letztlich entscheidet der persönliche Geschmack, das persönliche Anfreunden mit der Oberfläche und natürlich auch die Frage, ob das CMS alle Funktionen abdeckt, die man benötigt, ob WordPress das CMS erster Wahl ist. Und sicherlich haben viele – so auch ich – in der Vergangenheit ihr eigenes Content Management System geschrieben und haben einfach nicht mehr die Zeit, dieses System weiter zu pflegen. Und dort liegt auf jeden Fall eine der Stärken von WordPress: Das Open Source-Projekt wird von vielen fleißigen Händen gepflegt, ständig weiterentwickelt und auch zeitnah mit neuen Sicherheits-Patches versorgt. Da in meinem Fall der Code (die ersten Teile sind über acht Jahre alt) komplett neu geschrieben werden müsste, war es einfacher, auf WordPress zu wechseln.

Schritt 1: Die Basis-Installation
Die Installation von WordPress geht schnell von der Hand. Voraussetzung ist ein Webserver mit einer MySQL-Datenbank. Auf das Web wird am Besten die deutsche Version via FTP hochgeladen. Im Root der WordPress-Installation ist eine Datei namens „config.php“. Diese ist mit einem Texteditor zu öffnen. An den beschriebenen Stellen muss der Datenbankname, der Datenbank-Benutzer sowie das Passwort eingetragen werden. Die Datei benötigt auf dem Webserver die Rechte „777“.
Über den Browser wird das Web aufgerufen. WordPress meldet sich mit einem kurzen Installationsdialog. Lediglich die ersten Benutzerdaten und ein paar Textvariablen werden abgefragt. Fertig ist die Basisinstallation.

Schritt 2: Die Installation verfeinern
Es sollte dann unter dem Ordner „wp_content“ ein Ordner „uploads“ manuell angelegt werden. Dieser Ordner erhält die Rechte „777“. In diesen Ordner werden später alle Bilder und Medien, die von den Redakteuren in die Artikel eingefügt werden, zentral gespeichert.
Loggen Sie sich danach im Dashbord ein. In der Regel finden Sie einen Link „Anmelden“ (oder sie geben im Browser „domain.de/wp-admin“ ein). Es sollten unter „Einstellungen“ einige Angaben verfeinert werden. Die Zeitzone ist ggfls. einzustellen. Auch unter dem Punkt „Diskussion“ sollte geschaut werden. Wer die Kommentarfunktion „offen“ lässt, riskiert, dass blindwütige SEOs massenhaft Backlinks in Kommentare hinterlassen. Diverse blaue Pillen dürften sich auch schnell in den Kommentaren finden. Und letztendlich sind die Plugins zu installieren. Welche Plugins sinnvoll sind, das würde eine eigene Artikelserie füllen (und kommt vielleicht noch aus meiner Feder).

Weiter geht es im nächsten Teil unserer kleinen Serie: Artikel-Migration von CMS nach WordPress – Teil 2

WordPress: Mehrdimensionale Kategorien

WordPress bietet selbst in der aktuellen Version immer noch nicht die Möglichkeit, mehrdimensionale Kategorien anzulegen. Unter mehrdimensionale Kategorien versteht am übergeordnete Kategorien, die dann Kinder-Kategorien (Childs) unter sich gruppieren. WordPress legt die Kategorien alle in einer Ebene in der Tabelle wp_terms in einer Ebene ab. Gerade beim Umstieg von anderen Content-Management-Systemen (CMS) wie Drupal oder Typo3 wird man auf diese Möglichkeit nicht verzichten möchten.
Um mehrdimensionale Kategorien auch in WordPress zu erzeugen, bedient man sich am Einfachsten durch das Plugin „Folding Category List“. Dieses Plugin gibt Ihnen die Möglichkeit, solche mehrdimensionale Kategorien anzulegen.
Admin-EinstellungenInstallieren Sie zuerst das Plugin und aktivieren es. Gehen Sie danach unter EINSTELLUNGEN/FoCaL auf die Einstellungen des Plugins. Leider ist das Plugin nur auf Englisch zu haben. Diese Einstellungen müssen Sie jedoch nur einmal vornehmen. Passen Sie die „Individual Widgets“ sowie die SEO-Einstellungen individuell an.
Überprüfen Sie danach Ihr Design. Entfernen Sie zu erst das Kategorien-Widget Ihres bisherigen Designs. Das Plugin „Folding Category List“ bringt Ihnen ein eigenes Widget namens „FoCaL“ mit. Binden Sie dieses einfach durch anklicken mit der linken Maustaste und ziehen in Ihren Sidebar-Bereich ein. Lassen Sie das Widget durch loslassen der Maus „fallen“. Sie haben dann die Möglichkeit, durch anklicken („festheben“) und verschieben des Widgets, dieses in der Anzeigenreihenfolge zu verschieben.

Über das DropDown "Übergeordnet" legen Sie den Parent anNun überprüfen Sie die Kategorien bzw. legen neue an. Klicken Sie unter „Artikel“ auf „Kategorien“. Die werden sehen, dass es unterhalb der „Slug“-Textbox, die zur URL-Variante der Kategorien-Anzeige notwendig ist, eine Drop-Down-Box „Übergeordnet“ gibt. Wählen Sie nun eine Unterkategorie mit dem Link „Bearbeiten“ oder legen diese neu an. Wichtig ist, dass des die übergeordnete Kategorie bereits gibt (ansonsten wie gewohnt ohne eine Auswahl in der DropDown-Box „Übergeordnet“ anlegen). Geben Sie Ihrer Unterkategorie eine übergeordnete Kategorie mit.
Übergeordnete Kategorien müssen sie nicht explizit kennzeichnen. Per Default trägt jede Kategorie den Wert „keine“ im Feld „übergeordnet“.
Prüfen Sie nun, nachdem Sie drei oder vier Werte angepasst haben, das Ergebnis. Erscheint nun auf Ihrer Startseite die Hauptkategorie(n)? Wenn nein, prüfen Sie zuerst, ob Sie bereits Artikel in den entsprechenden Kategorien haben. WordPress zeigt nämlich per Standard keine leere Kategorien an.
Prüfen Sie danach noch mal unter „Einstellungen“ „FoCaL“ die Einstellungen. Hier können Sie zum Beispiel definieren, ob auch leere Kategorien angezeigt werden sollen. Ebenfalls beachten sollten Sie die „Global Settings“. Das Plugin „Folding Category List“ optimiert die Abfrage durch einen eigenen Cache. Diesen Cache sollten Sie unbedingt aktiviert lassen, da Sie dadurch einen Geschwindigkeitsvorteil haben. Überlegen sollten Sie sich, ob Sie die Checkbox im „Auto Rebuild Cache“ aktiviert lassen. Bei jeder Änderung an einem Artikel erstellt FoCaL den Cache für die Kategorien erneut. Da sich die Kategorien nur selten ändern, sollte diese Option meines Erachtens deaktiviert werden (Steigerung der Geschwindigkeit). Sie müssen nur daran denken, dass Sie den Cache neu erstellen (Button „Rebuild Cache“ unter dem Punkt „Enable Cache“ klicken), wenn sich Ihre Kategorien geändert haben. Ansonsten verweigert Ihnen FoCaL die Anzeige der neuen Kategorie.

HTML: Der Body der Webseite

Der Tag „body“ enthält alle sichtbaren Elemente einer Webseite. In diesem Container sind also alle Dateien einzufügen, die auf der Webseite angezeigt werden sollen. Von Texten über Grafiken bis zu Applets.
Probieren Sie folgendes Beispiel einmal aus:

<html>
<head>
<meta http-equiv="Content-Language" content="de">
<title>Meine erste Webseite</title>
</head>
<body>
Dies ist der Text innerhalb des Bodys
</body>
</html>

Dieser Text steht innerhalb des Body
Machen Sie einmal folgenden Test und schreiben Sie folgendes:

<html>
<head>
<meta http-equiv="Content-Language" content="de">
<title>Meine zweite Webseite</title>
</head>
<body>
Dies ist der Text innerhalb des Bodys
</body>
Dieser Text steht AUSSERHALB des Body
</html>

Die meisten Browser zeigen auch den Text außerhalb des Bodys an. Dies ist jedoch nicht richtig und kann zu Problemen führen. Im Body selbst können Sie weitere Parameter definieren, die das Aussehen der Webseite bestimmen. Folgenden Parameter sind möglich:

Die Textfarbe: Attribut „text“
Die Hintergrundfarbe: Attribut „bgcolor“
Die Hyperlinkfarbe: Attribut „link“
Die aktive Hyperlinkfarbe: Attribut „alink“
Die „besuchte“ Hyperlinkfarbe: Attribut „vlink“
Der Syntax des Body-Tag sieht dann folgendermaßen aus:

<html>
<head>
<meta http-equiv="Content-Language" content="de">
<meta http-equiv="refresh" content="5">
<title>Meine selbstaktualisierende Webseite</title>
</head>

<body bgcolor="green" link="yellow">
Dies ist der Text in Standardfarbe auf grünem Hintergrund.
<p><a href="http://www.google.de">Der Link zu google sollte in gelb erscheinen.</a></p>
</body>
</html>

Die Reihenfolge der Attribute ist beliebig. Auch ist es möglich, eine Farbe per Name oder per RGB-Wert anzusprechen. So ist also auch folgende Mischangabe möglich (wenn auch nicht „schön“):
<body bgcolor=“#008000″ link=“yellow“>
Neben der Möglichkeit, einer Webseite eine globale Hintergrundfarbe (“bgcolor”) mitzugeben, können Sie auch eine Grafik als Hintergrund einblenden Hintergrundbilder überdecken eine Hintergrundfarbe. Wenn die Grafik jedoch transparent definiert ist, so kann die Hintergrundfarbe in Vorschein treten.

<html>
<head>
<meta http-equiv="Content-Language" content="de">
<meta http-equiv="refresh" content="5">
<title>Meine selbstaktualisierende Webseite</title>
</head>

<body bgcolor="#008000" link="yellow" background="Pfad-zu-meinem-Bild.jpg">

Dies ist der Text in Standardfarbe auf grünem Hintergrund.
<p><a href="http://www.google.de">Der Link zu google sollte in gelb erscheinen.</a></p>
<p><font color="#008000">grgzrt</font></p>
</body>

</html>

Nicht zum HTML-Standard gehört das Attribut „bgproperties“. Damit erreichen Sie, dass das Hintergrundbild nicht mitscrollt. Je nach Browser wird dieses Attribut ignoriert.
Syntax: bgproperties=”fixed”

Sichere Passwort-Verschlüsselung

Die Tageszeitungen überschlagen sich mit den Meldungen, dass wieder und immer wieder Server bekannter Firmen geknackt wurden. Nach Sony hielt nun auch der Server des japanischen Videospielanbieters Sega einem Hackerangriff nicht stand. Und nicht selten ist zu lesen, dass diese Server die Passwörter ihrer Nutzer im Klartext gespeichert haben. Der Mensch neigt dazu, für viele Systeme das gleiche Passwort zu verwenden. Und so haben die Passwortdiebe meist schnell Zugriff auf andere Accounts des Bestohlenen. Hand aufs Herz: Haben Sie bei Paypal nicht das gleiche Passwort wie bei vielen anderen Webseiten? Es muss nicht weiter aufgeführt werden, was passieren kann, wenn der Server einer dieser Webseiten gehackt und die Passwörter, Namen und Email-Adressen gestohlen werden.

Kein Webserver ist wirklich zu 100 Prozent sicher. Tagtäglich finden Hacker irgendwelche Möglichkeiten, einen Server zu knacken. Dies wird sich nie ändern. Und ein guter Administrator weiß das. Und gerade, weil der Administrator dies weiß, ist es ein Unding, dass viele Webseiten die Passwörter nach wie vor im Klartext speichern. Ein kleiner Test zeigt, ob dies der Fall ist. Schauen Sie sich bei einer Webseite Ihrer Wahl um den Logindialog um, ob Sie einen Link finden, der Ihnen Ihr Passwort zuschickt. Dies ist eine gute Möglichkeit wieder Zugriff auf eine Webseite zu erhalten, falls man das Passwort vergessen hat. Wird jedoch mir genau das Passwort zugeschickt, das ich ursprünglich eingegeben habe, bedeutet dies, dass das Passwort nicht ausreichend verschlüsselt oder gar im Klartext in der Datenbank gespeichert wurde. Besser: Der Server setzt das Kundenpasswort zurück und verschickt ein Einmalpasswort.

Dabei ist es ein Einfaches, Passwörter verschlüsselt abzulegen. In der Regel funktioniert diese Technik so. Das Passwort wird intern immer verschlüsselt, also ein „Hash“ generiert. Der Hash aus dem „Einweg-Hash-Verfahren“  ist als solches für ein gleiches Passwort immer gleich. Rückschlüsse aus dem Hash zum ursprünglichen Passwort zu ziehen, ist nicht möglich.

<?php
// Passwort setzen
$passwort = 'mein_Pwd';

// Hash generieren
$hash = crypt($passwort);
?>

Beispiele von Hashs:

Standard DES: rl.3StKT.4T8M
Extended DES: _J9..rasmBYk8r9AiWNc
MD5:          $1$rafvgdfgle$rISCgZzpwk3UhDidwXvin0

Dies galt lange Zeit als sicher, da dieser Hash nicht zurückrechenbar ist. Wenn nun das Passwort überprüft werden muss, erfolgt die Generierung des Hashs der Benutzereingabe. Und diese wird mit dem gespeicherten Hash aus der Datenbank vergleichen.

if (crypt($benutzer_eingabe) == $hash_aus_datenbank) {
echo "Passwort stimmt überein!";
}

Erfolgt nun ein Angriff auf den Server und die Passwörter werden gestohlen, erhält der Dieb nur die Hashs der Passwörter. Eine Rückrechnung der Passwörter ist nach wie vor nicht möglich. Wohl aber das Durchprobieren (Brute Force) aller Passwortkombinationen mit Crackern wie beispielsweise John the Ripper ist möglich. Nicht ohne Grund wird für ein „sicheres“ Passwort eine Mindeststellenanzahl von acht angesehen. Wörter aus dem Lexikon sind zu vermeiden. So ein Passwort er entschlüsseln bedeutet eine Rechnerlaufzeit von Monaten bis hin zu Jahre. Findige Hacker optimieren diese Entschlüsselung, indem sie ganz einfach bereits bekannte Hashs in riesigen Tabellen (Rainbow Tables) speichern und diese Tabellen mit ihrem Hash vergleichen. So lassen sich „schwache Passwörter“ binnen Minuten entschlüsseln.
Doch auch in Sachen Hardware hat sich vieles getan. Einerseits ist es heute ohne Probleme möglich, sich Rechnerleistung nahezu beliebig via Internet zu mieten („Cloud-Computing“), andererseits sind speziell auf das Entschlüsseln von Passwörtern optimierte Server erhältlich. Wie man auch mit wenig finanziellem Aufwand seinen Rechner derart beschleunigen kann, zeigen die viele Beispiele der Bitcoin-Generierung. Das „Bitcoin-Mining“ ist nur lukrativ, wenn der Rechner deutlich mehr Rechenoperationen pro Sekunde durchführen kann, als ein normaler Standardrechner.

Wie kann man aber doch sicher ein Passwort ablegen?
Wenn ein Administrator das Standard MD5-Hash-Verfahren einsetzt, ist dies schon mal wesentlich besser, als Passwörter im Klartext zu speichern. Doch aufgrund von Rainbow Tables und der gestiegenen Rechenleistung kann dieses Verfahren ebenfalls nicht mehr als sicher angesehen werden. Eine gute Möglichkeit aus Nutzersicht die Sicherheit zu erhöhen, ist ein möglichst langes Passwort zu wählen. Für lange Passwörter ist es unwirtschaftlich, Rainbow Tables durch Vorberechnung anzulegen. Gleiches gilt für das direkte Ausprobieren (Brute Force).
Da aber das Nutzerverhalten zu möglichst kurzen Passwörtern neigt und keine Webseite seine Kunden zwingen kann, beispielsweise ein zwölfstelliges Passwort zu erzeugen, muss der Administrator dies für seine Nutzer machen. Das Passwort wird mit einer zufälligen Zeichenkette verlängert, auch Salt genannt. Erst von diesem neuen Passwort wird der Hash erzeugt. Für den Vergleich der Hash muss dieser Salt allerdings bekannt sein. Also wird der zufällig erzeugte Salt dem Hash einfach vorangestellt und gespeichert. Klingt Widersprüchlich? Ja, aber es funktioniert. Das Ziel des Salt ist es, das Passwort aufzublähen und somit den Aufwand zum Anlegen von Rainbow Tables massiv zu vergrößern. Ein zufällig generierter Salt erfüllt diesen Zweck.

Salz in der Suppe: Salt und Hash
Das Passwort ist somit immer noch nicht zu 100 Prozent sicher geschützt. Die Konzentration des Hackers auf ein bestimmtes Passwort lassen den Hacker je nach Rechenleistung in vertretbarer Zeit zum Ziel kommen. Mehrere oder gar alle Passwörter einer Datenbank zu entschlüsseln, die mit Salt verschlüsselt wurden, ist derzeit fast unmöglich.
Aber auch dieses Verfahren lässt sich noch verbessern. Aktuell ist die beste Methode, ein Passwort zu verschlüsseln, den per Salt gewürzten Hash immer und wieder zu wiederholen. Diese gewollte Verlangsamung hat den Vorteil, dass der Hacker dies ebenfalls für jede Passwortkombination wiederholen müsste. Die Webanwendung, die den Hash bei der Passwortüberprüfung so ermitteln muss, benötigt so viel länger. Von einer Mikrosekunde auf vielleicht eine Millisekunde. Dies merkt der Nutzer nicht. Der Administrator lediglich durch seine höhere Serverlast. Wer aber wirklich massiv ausgebremst wird, ist der Hacker. Aktuell schaffen optimierte Passwortgeneratoren rund 100 Millionen Passwörter pro Sekunde. Wenn ein Passwort beispielsweise 1000 mal gehasht wird, kann der Passwortgenerator lediglich 100.000 Passwörter pro Sekunde erzeugen und vergleichen. Dies bedeutet, dass ein Brute-Force-Angriff auf ein einfaches achtstelliges Passwort von bisher 18 Tagen auf 48 Jahre verlängert wird. Aktuell kann dies für den Hacker als unwirtschaftlich angesehen werden.

Retargeting: Personalisierte Werbung

Zwangsläufig beschäftigt sich jeder Mensch mit Werbung. Denn diese ist immer und überall. Ob sie einen interessiert oder nicht. Das Internet bietet den Werbetreibenden die Möglichkeit, Werbung zielgerichtet zu präsentieren. Eigentlich eine gute Sache, denn Werbung für die neuste Make-Up-Produkte der Pariser Schönheitsindustrie interessieren mich – als Mann – eigentlich wenig. Vielleicht zu Weihnachten, wenn ich wie gewöhnlich in letzter Minute ein Geschenk für die Frau suche.
Dass zielgerichtete Werbung funktioniert, habe ich bereits vor knapp zwei Jahren entdeckt. Mehrere Tage war ich im Netz unterwegs, um die Auswahl eines neuen LCD-TV zu treffen. Nachdem ich alle Technikmärkte in der Umgebung abgeklappert hatte, aber nicht deutlich schlauer war, versuchte ich über das Intranet Informationen zu erhalten. Der Preisvergleich war eher eine Randerscheinung.
Nach ausgiebiger Recherche hatte ich mich auf ein Produkt festgelegt und war umso erstaunter, als ich tags darauf wieder am PC surfte. Auf meiner gewohnten Online-TV-Programmauskunftsseite erschien plötzlich ein Banner, der mir just dieses TV-Modell eines bekannten Händlers präsentierte. Auch einige andere Seiten wussten offenbar, dass mich dieses Thema interessierte. Mich persönlich hat dies eher erschreckt. Und nach dem Löschen der Browsercookies hatte der Spuk ein Ende.
Dass Betreiber von E-Commerce Webseiten die sogenannte Conversion Rate, also die Anzahl der Besucher der Webseite, die auch zu Kunden werden, steigern wollen, ist verständlich. Und in der Regel bietet das Retargeting, die zielgerichtete Werbung, dem Kunden nur Vorteile. Nur wenige Kunden dürften wie ich verschreckt sein im Hinblick auf Datenschutz und der technischen Möglichkeit, personalisierte Anzeigen so genau zu präsentieren. Die Firma TellApart ist beispielsweise eine der Agenturen, die sich auf diesen Anzeigenhandel spezialisiert hat. Ihren Angeben zur Folge klicken rund 7,5 Prozent der Besucher auf personalisierten Anzeigen. Klingt nach keinem großen Erfolg, ist aber eine deutlich höhere Click-Through-Rate als bei bisheriger statischer Werbung. Wichtig für den Händler ist der Verkaufsabschluss. Und dieser soll bei 4,5 Prozent liegen. Also rund fünf von hundert Kunden, die über Retargeting auf einen Webshop geleitet werden, bringen dem Händler den ersehnten Umsatz. Von dieser Höhe können viele Werbetreibende nur träumen.
Über die Technik im Hintergrund schweigen die Datensammler selbstverständlich. Aber auch ohne Auskunft liegt auf der Hand, wie das Retargeting funktioniert. Über den Referer des Browsers lässt sich ermitteln, welche Seite den Benutzer zuvor besucht hatte. Schon daraus lässt sich ableiten, wonach der Besucher auf der Suche ist. Auch offensichtliche Daten wie die IP-Adresse sowie die Uhrzeit hilft den Kunden weiter zu klassifizieren. Liefert ein weiterer Kunde des Retargeting-Dienst weitere Informationen, ist der Kunde klar definiert. Sucht er bei einem Shop ein bestimmtes Produkt, und nur dieses, ist er wahrscheinlich auf der Suche nach dem besten Preis. Hat er sich beim ersten Shop beispielsweise mehrere Fernseher angesehen, vielleicht einer bestimmten Marke, liegt auf der Hand, wonach der Kunde auf der Suche ist. Gerät der Kunde dann auf eine weitere Seite mit Werbeeinblendung über den Retargeting-Dienst, versprechen Werbebanner, die TV-Geräte präsentieren, den größten Erfolg.
Dass bei der Erhebung der Kundendaten riesige Datenmengen anfallen, liegt auf der Hand. Spannend nicht nur für Datenbankadministratoren wäre zu erfahren, wie die Speicherung und wie lange die Aufbewahrung der Daten erfolgt. Aus Datenschutzgründen ebenfalls interessant wäre die Frage, ob die Zuordnung der gespeicherten Daten mit Löschen des Cookies und dem Wechsel der IP-Adresse aufgehoben ist. Doch darüber schweigen die Macher.
Dass sie ihr Handwerk beherrschen, zeigen die Erfolge. Und dass sie ihr Handwerk von der Pike auf gelernt haben, zeigt deren Lebenslauf: Ihr vorheriger Arbeitgeber war die Datenkrake Google.

WordPress Plugin WP-PDA auf Deutsch installieren

Die Zugriffe über mobile Browser werden immer häufiger. Grund genug, auch für diese Browser optimierte Seiten bereitzustellen. Wer seine Webseite mit dem Content Management System WordPress erstellt, kann dies mit der Installation eines einfachen Plugins erledigen.
Die Setup-Seite ist aufgeräumt: Es gibt nichts zu konfigurierenDas Angebot ist reichhaltig. Ich habe einige der kostenlosen Plugins getestet. Manche sind gut, manche weniger gut. Viele erfordern viel Arbeit bei der Installation oder bei der Konfiguration. Letztendlich habe ich mich für das Plugin WP-PDA entschieden, denn dieses Plugin ist einfach zu installieren (Standard) und muss nicht konfiguriert werden. Plug and Play sozusagen.

Doch einen Nachteil hat das Plugin. Es wird nicht auf Deutsch angeboten. Und das hat mich gestört. So sehr, dass ich mich mit Übersetzungstabellen, .mo und .po-Dateien und anderen Programmen beschäftigt habe. Nach viel herumprobieren, grauen Haaren und wüsten Flüchen, habe ich es geschafft. Das Plugin spricht auf dem mobilen Browser deutsch.

Ich stelle Euch hier die wp-pda Sprachdateien zum Download bereit. Geht wie folgt vor:

  1. Installiert über WordPress das Plugin WP-PDA. Aktuelle Version für diese Anleitung ist die 1.3.1. Die Sprachdateien sollten auch für folgende Versionen kompatibel sein.
  2. Ruft Eure Seite über einen mobilen Browser (Handy, PDA) auf. Ihr solltet nun Eure Seite aufbereitet über das Plugin sehen.
  3. Das Plugin hat zwei Templates. Es unterscheidet zwischen Aufrufen per PDA („pda-theme“) und Aufrufen durch mobile Browser („jqmobile-theme“), zu dem das IPhone, IPod sowie Android-Browser gehören.
  4. Die deutsche Sprachdatei für das PDA-Template könnt Ihr hier herunterladen. Kopiert diese über einen FTP-Browser in das Verzeichnis „/wp-content/plugins/wp-pda/pda-theme“ und benennt die Datei in „pda-theme-de_DE.mo“ um.
  5. Die deutsche Sprachdatei für das jqmobile-theme könnt Ihr hier herunterladen. Diese Datei bitte ebenfalls per FTP, allerdings in das Verzeichnis „/wp-content/plugins/wp-pda“ kopieren und ebenfalls umbenennen in „pda-theme-de_DE.mo“.
  6. Ein erneuter Aufruf Eurer WordPress-Seite sollte nun eine deutschsprachige Oberfläche zeigen.
  7. Ihr werdet sehen, dass zumindest in der Version 1.3.1 die Buttons unten weiterhin in englischer Sprache sind. Dies ist ein Fehler des Programmierers, denn er hat die Buttons nicht in eine Sprachdatei mit einbezogen. Ich habe den Entwickler darauf hingewiesen. Evtl. wird in einer neueren Version der Fehler behoben. Wenn die Buttons in deutscher Sprache erscheinen, könnt Ihr den Punkt hier abbrechen.
  8. Ladet die Datei single.php aus dem Ordner „/wp-content/plugins/wp-pda/jqmobile-theme“ auf Euren Rechner herunter und öffnet die Datei mit einem einfachen Texteditor (Windows: Notepad o.ä. KEIN Word oder eine andere Textverarbeitungssoftware!)
  9. Sucht die folgende Stelle:
    <?php previous_post_link('%link','Previous') ?>
    <?php next_post_link('%link','Next') ?>
  10. Ersetzt die Zeilen durch folgende:
    <?php previous_post_link('%link',__('Previous Page','pda-theme')) ?>
    <?php next_post_link('%link',__('Next Page','pda-theme')) ?>

    Ersetzt nun die Datei “single.php” auf Eurer WordPress-Installation auf dem Webserver.

  11. Das Plugin spricht jedoch noch immer nicht zu 100 Prozent deutsch. Diesmal ist es kein Fehler des Programmierers, sondern ein Problem des Frameworks, das der Programmierer nutzt. Basis des Webaufbaus ist das JQuery-Framework jquery.mobile-1.0a2.min.js von http://jquerymobile.com. Diese Datei wird automatisch bei jedem Seitenaufbau geladen. Und soweit ich weiß, gibt es das Framework nur auf Englisch. Die folgenden Modifikationen stehen meines Erachtens in keinem Verhältnis zum Aufwand, so dass die meisten Installationen damit leben sollen, dass es einen „Back“-Button und ein „loading“-Fenstern gibt. Wer dies noch beheben möchte, der kann die folgenden Schritte unternehmen.
  12. Ladet Euch das Framework unter „http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js“ herunter.
  13. Öffnet die Datei über einen Texteditor. Es handelt sich um komprimiertes JavaScript. Keine Sorge, Ihr müsst den Code nicht verstehen. Sucht mit Hilfe des Texteditors die Stelle „loadingMessage:“loading““ und „backBtnText:“Back““. Ersetzt die Worte innerhalb der Hochkommas. ACHTUNG: Nur die Worte ersetzen, keine Hochkommas löschen!
  14. Da das Framework bisher von http://jquerymobile.com geladen wurde, Ihr aber Änderungen vorgenommen habt, müsst Ihr diese Datei nun auf Euren Webserver lokal bereitstellen. Ladet die Datei auf Euer Web hoch.
  15. Schaut Euch die header.php-Dateien in den beiden Template-Ordner an. Passt die Zeile <script type=“text/javascript“ src=“http://code.jquery.com/mobile/1.0a2/jquery.mobile-1.0a2.min.js“></script> so an, dass der Link auf Eure modifizierte js-Datei zeigt.  Geschafft. Fertig sind die Änderungen.
  16. Nachteile der Modifikation des JQuery-Framework: Das Laden der Datei über das Web von jquerymobile.com hat zwei entscheidende Vorteile, die durch Eure Modifikation verloren gehen. Zum einen erspart Ihr Euch Traffic (und vielleicht auch Kosten), da die Datei jedes mal nicht von Eurem Server geladen wird. Ferner bekommt Ihr nicht mit, wenn die Entwickler die Datei ändern bzw. verbessern. Diese Nachteile haben allerdings auch Vorteile: Sollte mal der Webserver von jquerymobile offline sein, läuft Euer Web immer noch. Auch könnt Ihr sicher sein, dass Euer Web noch läuft, selbst wenn die Entwickler eine neu Version (mit neuem Namen/Link) veröffentlichen und diese Version von ihrem Webserver löschen. Wie bei allem gibt es zwei Seiten der Medaille…

WordPress Plugin auf deutsch übersetzen

WordPress ist eine wunderbares CMS. Und das wirklich wunderbare ist, dass es unzählige Plugins und Themes gibt, die größtenteils auch kostenlos angeboten werden. Doch was stört ist, dass nicht immer alles in deutscher Sprache bereitgestellt wird. WordPress an sich wird in einer deutschen Version bereitgestellt. Hier sind viele fleißige Hände am Werk, die dies bewerkstelligen (dies ist ein Lob!). Doch eben nicht alles, was man zusätzlich installieren möchte, ist in deutscher Sprache zu haben (siehe auch hier).

WordPress nutzt GetText für die Lokalisierung der Sprache. Wenn man sich an diesen Standard hält, können weitere Sprachen ohne Änderung des Quelltextes einfach durch hinzufügen einer weiteren Sprachdatei hinzugefügt werden. Als Basis dient die Einstellung der Sprache innerhalb von WordPress. Im Deutschen ist „de_DE“ voreingestellt. Somit versuchen sämtliche Komponenten, eine Sprachdatei zu finden, die diese Kodierung enthält. Wenn nicht, wird der „default“ der Komponente angezeigt.

So geht Ihr vor:
Zuerst muss ermittelt werden, ob der Programmierer überhaupt an eine Mehrsprachigkeit gedacht hat. Wenn die einzelnen Sprachfragmente „hardcoded“ im Text stehen, dann müsst Ihr diese mühsam Stelle für Stelle ändern. Ihr erhaltet dann eine eigene Version der Komponente, die mit jeder Veröffentlichung des ursprünglichen Programmierers automatisch veraltet ist. Also eine schlechte Methode.
Schaut in den Ordnern der Komponente nach, ob Ihr auf .mo-Dateien (Beispiel: „pda-theme-de_DE.mo“) stoßt. Dies ist ein erster Hinweis, dass der Programmierer an Mehrsprachigkeit gedacht hat. Allerdings sollte keine „de_DE.mo“ Datei zu finden sein. Denn wenn diese Datei vorhanden ist, die Komponente in einer anderen Sprache zu Euch spricht, dann ist was anderes faul ….
Gehen wir davon aus, dass andere Sprachen vorliegen. Dann schaut sicherheitshalber Euch mal eine PHP-Seite aus der Komponente an. Ihr solltet innerhalb des Codes auf Stellen wie

__('Edit','pda-theme');

oder

_e('by','pda-theme');

stoßen. Also Funktionen, die mit zwei Unterstrichen „__“ oder mit „_e“ beginnen. Dies bedeutet, dass hier eine Sprachdatei eingebunden wurde. Den Namen der Datei steht als zweiter Parameter innerhalb der Klammer. In diesem Beispiel ist es „pda-theme“. Der erste Parameter der Klammer (hier „Edit“ und „by“) ist der Text in Originalsprache.

Kurzer .mo und .po-Ausflug
Die mo-Datei (Machine Object) ist eine kompilierte Version der Sprachdatei. Dies ist Euer Ziel. Diese Datei kann im Prinzip nicht mehr geändert werden, sondern muss von Euch neu erzeugt werden. Ausgang Eurer Übersetzung ist eine Datei, die mit .po (oder .pot. – Portable Object Template – Template für tragbare Objekte) endet. Diese Datei könnt Ihr einmal mit einem Texteditor öffnen. Ihr entdeckt darin folgenden Aufbau:

#
#: archive.php:19
#: search.php:6
msgid "Search Results"
msgstr "Suchergebnisse"

Die MessageID („msgid“) bezeichnet die Textstelle (erster Parameter der Funktion „__“ oder „_e“) sowie den „msgstr“, also die Übersetzung. Wenn Ihr die „default.po“ findet, sollte der Message-String leer sein (msgstr „“), da ja noch keine Übersetzung in diesem Template vorhanden ist.
Theoretisch könnte man die Übersetzung schon jetzt via Texteditor vornehmen, doch wir brauchen eh ein spezielles Tool für die Erstellung der .mo-Datei. Daher von dieser Idee erst einmal Abstand nehmen.

Es ist keine .po oder .pot-Datei vorhanden
Nun, man kann dann beim Programmierer nachfragen. Oder man erstellt sich diese Datei selbst. Ich selbst habe unzählige Stunden googeln hinter mir, bis ich ein Tool gefunden habe, das diese Aufgabe erledigt. Und dies möchte ich Euch nicht vorenthalten. Es ist ein Online-Converter. Hier könnt Ihr einzelne Dateien, aber auch ein ganzes Projektverzeichnis konvertieren. Gerade letzteres ist wichtig, denn die wenigsten Plugins oder Templates bestehen nur aus einer Datei.

.po-Dateien übersetzen und .mo-Datei erstellen
Hier bemühen wir ein Tool, das den treffenden Namen poedit trägt. Dieses Tool einfach installieren und starten. Nach einigen selbsterklärenden Fragen habt Ihr die Möglichkeit, die .po-Datei zu laden. Nun kann jedes Wort oder Satzelement beliebig übersetzt werden (dies könnte man auch direkt in der Textdatei erledigen). Beim Speichern jedoch erstellt poedit automatisch die notwendige .mo-Datei.

Richtige Namensgebung
Geben Sie schon der .po-Datei, wenn Sie diese selbst erstellen, einen passenden Namen. Der Dateiname ist normalerweise wie folgt aufgebaut: Der erste Bestandteil des Dateinamen ist i.d.R. der Name des Komponente. Wenn weitere .mo-Dateien vorhanden sind, richten Sie sich an diesen Dateien. Wenn nicht, schauen Sie in den Quelltext der php-Dateien. Der zweite Parameter der „__“ und „_e“-Funktionen bestimmt den Namen der Datei. Es folgt ein „-„ und dann für die deustche Sprache ein „de_DE.mo“ bzw „.po“. Wenn Sie also in den php-Dateien den Funktionsaufruf „__(‚Edit‘,’pda-theme‘)“ finden, muss Ihre Datei mit „pda-theme“ starten. Der korrekte Dateiname lautet in unserem Beispiel: „pda-theme-de_DE.mo“

Wohin die .mo-Datei kopieren?
Wenn mehrere .mo-Dateien vorhanden sind, haben Sie es einfach: .mo-Dateien unterliegen einem „Gruppenzwang“ und sind ungern alleine … ? Also einfach zu den anderen Dateien hinzukopieren.
Wenn Sie diese Hilfe nicht haben, müssen Sie den php-Quelltext bemühen. Achten Sie auf den Funktionsaufruf „load_theme_textdomain“, also beispielweise:

load_theme_textdomain('pda-theme');

Sie müssen sich an diesen Aufruf halten (oder das Projekt entsprechend anpassen. Weitere Hinweise und Beispiele zu load_ theme_textdomain erhalten Sie bei wordpress.org.

Internet-Explorer (IE) steuern mit C#

Die Anwendungsmöglichkeiten sind vielfältig. Von kleinen SSO (SingleSignOn)-Lösungen bis hin zur kompletten Automation: Das automatische Steuern des IE kann ganz nützlich sein. Schon unter VB6 konnte auf das Webmodell des IE zugegriffen werden. Wer endlich den Umstieg zu .NET schafft, wird allerdings erst einmal relativ wenig darüber finden. Beeindruckend sind die Möglichkeiten allemal.
Zumal für die meisten Aufgaben noch nicht einmal der IE benutzt werden muss. Will man nur den HTML-Code oder ein XML auslesen, ist mal über den WebRequest bestens bedient. Selbst ein Proxy ist so anzusprechen.

Beispiel 1: WebRequest für die Rückgabe von HTML oder XML

//sURL: Die Ziel-URL
WebRequest request = WebRequest.Create(sURL);

//Webproxy mit den Parametern sUser, sPasswort, sDomain, sPort
//    WebProxy proxy = new WebProxy(sWebProxy, Convert.ToInt32(sPort));
//    proxy.UseDefaultCredentials = true;
//    proxy.Credentials = new NetworkCredential(sUser, sPasswort, sDomain);
//    request.Proxy = proxy;

WebResponse response = request.GetResponse();
Stream streamResponse = response.GetResponseStream();

StreamReader streamRead = new StreamReader(streamResponse, Encoding.Default);
Char[] readBuff = new Char[256];
int count = streamRead.Read(readBuff, 0, 256);
string xmlData = "";
while (count > 0)
{
String outputData = new String(readBuff, 0, count);
xmlData += outputData;
count = streamRead.Read(readBuff, 0, 256);
}

// Close the Stream object.
streamResponse.Close();
streamRead.Close();
response.Close();

//xmlData beinhaltet nun den Code
return xmlData;

Das Beispiel 1 erweist sich als äußerst stabil und zuverlässig. Doch nicht wenige Webprogrammierer schieben einer solchen Abfrage einen Riegel vor und liefern 404 (Fehler) zurück, um eben das Auslesen des Codes zu verhindern. In einem solchen Fall kann man einen speziellen Header schicken, um dem Webserver einen Browserzugriff vorzugaugelen, oder eben den Browser bemühen, die Abfrage zu erledigen.
Gerade wenn man noch weitere Aktionen im Dialog mit der Webseite vorhat, kommt man kaum um den Browser herum.

Beispiel 2: IE-Browser mit C# steuern

//Erstelle den IE
object o = null;
InternetExplorer ie = null;

ie = new InternetExplorerClass();
IWebBrowserApp wb = (IWebBrowserApp)ie;
wb.Navigate("http://www.google.de", ref o, ref o, ref o, ref o);
wb.Visible = true;

Sobald Sie sich mit dem Webbrowser beschäftigen, sind in der Regel die untenstehende Verweise notwendig. Die entsprechenden Referenzen für MSHTML und SHDOCVW findet Sie unter COM -> Microsoft HTML Object Library  oder .NET -> Microsoft.mshtml für MSHTML und COM -> Microsoft Internet Controls für SHDOCVW.

using SHDocVw;
using mshtml;

Beispiel 3: HTML-Code aus Webseite auslesen

Wenn der Browser wie in Beispiel 3 geöffnet und die Seite angezeigt wurde, kann man auch auf den HTML-Code zugreifen:

//Warte - hier gibt es bessere Möglichkeiten
while (wb.Busy) ;
HTMLDocument wd = (HTMLDocument)wb.Document;

//HTML-Code
IHTMLDocument2 doc = (IHTMLDocument2)ie.Document;
string sHTML = doc.body.innerHTML;

Beispiel 4: Zugriff auf die HTML-Elemente

Man kann einfach über den TagName auf die Elemente zugreifen

//Alle Elemente
IHTMLElementCollection eventLinks = (IHTMLElementCollection)wd.getElementsByTagName("a");

//Diese können dann zum Beispiel mit Foreach durchgegangen werden
foreach (HTMLAnchorElementClass el in eventLinks)

Beispiel 5: Einen bestimmten Link klicken

IHTMLElementCollection linkElems = doc.links;
foreach ( HTMLAnchorElementClass linkl in linkElems)
{
    //a href -> URL des Links
     string sLink = link.href.ToString();

    //Link Klicken mit:
    link.click();
}

Beispiel 6: Manipulation von HTML-Elementen

Auch lassen sich mit C# und dem Objektmodell die Eigenschaften der Tags abfragen und ändern. Folgendes Beispiel ändert beispielsweise alle Targets der Hyperlinks von „_blank“ auf „_self“; alle Links öffnen sich also nur noch im gleichen Fenster.

    HTMLDocumentClass doc = (HTMLDocumentClass) this.webBrowser.Document;
    IHTMLElementCollection all = (IHTMLElementCollection) doc.all;
    IHTMLElementCollection anchors = (IHTMLElementCollection) all.tags("A");
    foreach (HTMLAnchorElement a in anchors)
    {
        if (a.target.Equals("_blank", StringComparison.OrdinalIgnoreCase))
        {
            a.target = "_self";
        }
    }

Beispiel 7: Textbox mit C# füllen und Submit-Button klicken

//Beispiel: Rufe google auf, fülle die Textbox und klicke den Button
object o = null;
InternetExplorer ie = null;

ie = new InternetExplorerClass();
IWebBrowserApp wb = (IWebBrowserApp)ie;
wb.Navigate("http://www.google.de", ref o, ref o, ref o, ref o);
wb.Visible = true;

while (wb.Busy) ;
HTMLDocument doc = (HTMLDocument)wb.Document;

//Die Google-Textbox "q" ansprechen
IHTMLElement inputValue = doc.getElementById("q");

//ändere das Attribut "value" mit dem Such-Inhalt
inputValue.setAttribute("value", "Meine Suche");

//Button ansprechen
IHTMLElement submitButton = doc.getElementById("btnG");

//Button klicken
submitButton.click();

Weitere Links:
Zugriff auf Frames/iFrames

Email-Migration von Outlook 2000 zu Windows Live Mail (über Outlook Express)

Der Datenübertrag von Email-Programmen zur nachfolgenden Version ist meistens kein großes Problem. Anders sieht es aus, wenn man mehrere Versionen „ausgesessen“ hat und heute plötzlich damit konfrontiert wird, seine Daten zu migrieren. Im vorliegenden Fall geht es um dem Umstieg von Outlook 2000 zu Windows Live Mail.
Kontakte lassen sich bequem per Visitenkarte exportieren und in Windows Live Mail importieren (Kontakte in Windows Live Mail importieren). Auch der Kalender-Import klappt schnell und reibungslos. Die Email-Konten an sich stellen auch kein Problem dar. Anders sieht es mit den vielleicht vielen Ordner aus, in denen sich Mails um Mails tummeln. Jedes Exportieren/Importieren zwischen diesen zwei Anwendungen ist leider zum Scheitern verurteilt. Auch die Idee, die Mails per Drag and Drop ins Dateisystem zu kopieren (Ziehen Sie eine Mail aus Outlook 2000 in einen Explorer-Ordner, legt sich die Mail als Outlook-Element („.msg“) inklusive eventuell vorhandener Anlagen sauber im Dateisystem ab. Doch jeder Versuch, diese Mails dann in Windows Live zu importieren, wurden zumindest bei mir von Windows Live negativ quittiert.
Nach langem Suchen, googeln und ausprobieren habe ich einen gangbaren Weg gefunden, der jedoch auch nicht optimal ist. Da es sich jedoch um einen einmaligen Vorgang handelt, kann dieser Weg für die meisten eine gute und relativ schnelle Lösung darstellen.
Da ich keinen Weg gefunden habe, direkt die Mails von der einen zur anderen Outlook-Variante zu migrieren, musste ein Zwischenschritt her. Dieser Zwischenschritt ist „Outlook Express“ bzw. „Outlook Express 6“. Diese Abwendung muss kurz installiert werden. Nach erfolgreicher Migration der Daten können Sie Outlook Express wieder schnell entfernen.

Installieren Sie zuerst Outlook Express auf Ihrem Windows-Klient. Microsoft selbst scheint diese Anwendung nicht mehr zum freien Download anzubieten. Per google sind viele wenig vertrauenswürdig bekannte Quellen zu finden, von denen ich alle Abstand halten würde. Zumal Outlook Express bei Windows XP wohl standardmäßig dabei war. Wenn Sie Outlook Express nicht mehr unter Start/Programme finden, wurde die Anwendung evtl. entfernt oder erst gar nicht bei der Systemerstellung installiert. Prüfen Sie daher, ob die Installation einfach möglich ist (unter XP sollte dies der Fall sein). Starten Sie das Menü Software unter Start/Systemsteuerung/Software. Klicken Sie im linken Bereich auf „Windows-Komponenten hinzufügen/entfernen“. Im „Assistent für Windows-Komponenten“ finden Sie in der „Komponentenliste“ den Eintrag „Outlook Express“. Klicken Sie die Checkbox vor „Outlook Express“, damit dort der Haken gesetzt ist. Windows XP wird nach dem Klick auf den Button „Weiter“ Outlook Express installieren. Eventuell müssen Sie die System-CD nach Aufforderung einlegen.
Wenn der Dialog abgeschlossen wurde, können Sie Outlook Express via Start/Programme starten. Die Meldung, ob „Outlook Express“ der neue Standard-Mailclient werden soll, können Sie mit „Nein“ beantworten. Denn wir möchten uns nur kurz mit Outlook Express beschäftigen. Wählen Sie Datei/Import/Ordner. Mit etwas Glück findet Outlook Express die PST-Datei von Outook 2000 automatisch und bietet Ihnen an, die Daten zu importieren. Bestätigen Sie die Meldung. Je nach Umfang der Daten kann dieser Vorgang eine ganze Weile dauern.
Wenn die Daten in Outlook Express importiert sind, schließen Sie die Anwendung. öffnen Sie Windows Live Mail und wählen dort ebenfalls den Punkt „Import“. Wählen Sie als Quelle „Outlook Express“ und importieren Sie die Daten, die Sie gerade nach Outlook Express  importiert haben. Nach erfolgreichem Abschluss des Imports, der ebenfalls einige Zeit dauern kann, haben Sie Ihre Mails in einem neuen „Speicherordner“ in Windows Live Mails. Klicken Sie diese Ordnerstruktur auf. Unter „Importierter Ordner“, „Lokale Ordner“ finden Sie Ihre bisherige Ordnerstruktur, evtl. sogar inklusive Ihrer gelöschten Mails. Diese Ordner können Sie dann innerhalb von Windows Live Mail nach Ihrem Geschmack verschieben und anpassen.
Wenn alle Daten importiert sind, können Sie Outlook Express wieder entfernen (Haken entfernen unter „Windows-Komponenten hinzufügen/entfernen“).