Welches Mail-Programm sich öffnet kannst du nicht beeinflussen. Das legt die Konfiguration im Betriebssystem deiner Kundin fest.
Unter Windows 10 lässt sich das in den Einstellungen unter System -> Standard-Apps ändern.
Welches Mail-Programm sich öffnet kannst du nicht beeinflussen. Das legt die Konfiguration im Betriebssystem deiner Kundin fest.
Unter Windows 10 lässt sich das in den Einstellungen unter System -> Standard-Apps ändern.
Hier habe ich dazu mal eine kleine Anleitung verfasst.
Auf der Suche nach offenen Fragen im Forum stieß ich auf einen Thread, in dem nach einer Anleitung für eine transparente Hintergrundgrafik mit Schrift gesucht wurde.
Aus diesem Anlass möchte ich hier kurz erklären, wie man das ganz einfach umsetzen kann.
Ich erkläre am Beispiel der freien Bildbearbeitungssoftware Gimp (Version 2.8.16) und Adobe Photoshop CC (Version 2015.1.2).
Was wird benötigt?
Gimp (kostenlos) oder Photoshop (nach Testphase kostenpflichtig). Für solch eine einfache Aufgabe eignen sich beide Programme hervorragend.
Schritt 1: Datei erstellen
Sowohl in Gimp, als auch in Photoshop lassen sich Dateien über die Menüpunkte File -> New, oder über die Tastenkombination STRG + N anlegen. Die Dialoge unterscheiden sich ein wenig. Zuerst muss eine Größe her. Ich werde für dieses Beispiel eine Breite von 500px und eine Höhe von 250px nutzen.
Einstellungen Gimp:
Width: 500px
Height: 250px
(!) Klick auf Advanced Options
Fill with: Transparency
html-seminar.de/woltlab/attachment/934/
Einstellungen Photoshop:
Width: 500px
Height: 250px
Background Contents: Transparent
html-seminar.de/woltlab/attachment/935/
Durch die Einstellungen ist der Hintergrund des Bildes schon transparent. Das erkennt man auch an dem grauen Schachbrettmuster. Wenn kein Schachbrettmuster, sondern z. B. ein weißer Hintergrund zu sehen ist, ist etwas schiefgelaufen. Einfach noch mal probieren und darauf achten, die Einstellungen korrekt zu justieren. Wenn auch das nicht klappt, wie folgt vorgehen:
Transparenz erzwingen mit Gimp:
Im Fenster mit dem Titel Layers - Brushes ein Rechtsklick auf die Ebene mit dem Namen Background. Dann Add Alpha Channel auswählen. Wenn die Option ausgegraut ist, ist dieser bereits vorhanden und es kann weitergehen. STRG + A (Select -> All) und dann ENTF (Edit -> Clear) drücken. Jetzt sollte das Schachbrettmuster zu sehen sein.
Transparenz erzwingen mit Photoshop:
Im Ebenen Dialog Rechtsklick auf die Ebene mit dem Namen Background. Dann Layer from Background. Das auftauchende Fenster mit OK bestätigen. Wenn die Option fehlt (und viele Optionen angezeigt werden), ist der Schritt bereits geschehen. STRG + A (Select -> All) und dann ENTF (Edit -> Clear) drücken. Jetzt sollte das Schachbrettmuster zu sehen sein.
Schritt 2: Text einfügen
Text erstellen mit Gimp:
Zuerst in der Toolbox die Vordergrundfarbe wie gewünscht einstellen. Ich nehme schwarz. Danach ein Klick in der Toolbox auf das große A oder einfach auf der Tastatur auf T gedrückt und das Text Werkzeug ist ausgewählt. Ein Klick ins Bild erstellt nun eine neue Textebene in der geschrieben werden kann. Die Bedienung ist sehr intuitiv. Im unteren Bereich der Toolbox sind einige Einstellungen aufgetaucht wie z. B. Schriftart, Größe, Farbe, Ausrichtung. Einfach Experimentieren. Mit einem Klick in der Toolbox auf das Symbol mit den 4 Pfeilen in jede Richtung oder M auf der Tastatur wird das Werkzeug zum Verschieben ausgewählt. Um den Text erneut zu bearbeiten, muss lediglich das Textwerkzeug ausgewählt und auf den entsprechenden Text geklickt werden.
Mit diesen Werkzeugen lässt sich der Text drehen, spiegeln, oder verzerren:
html-seminar.de/woltlab/attachment/936/
Text erstellen mit Photoshop:
Zuerst die Vordergrundfarbe wie gewünscht einstellen. Ich nehme schwarz. Danach ein Klick in der Werkzeugleiste auf das große T oder einfach auf der Tastatur auf T gedrückt und das Text Werkzeug ist ausgewählt. Ein Klick ins Bild erstellt nun ein neues Textobjekt in dem geschrieben werden kann. Die Bedienung ist sehr intuitiv. Am oberen Rand unter dem Menü sind einige Einstellungen aufgetaucht wie z. B. Schriftart, Größe, Farbe, Ausrichtung. Einfach Experimentieren. Mit einem Klick in der Werkzeugleiste auf das Symbol mit den 4 Pfeilen in jede Richtung oder V auf der Tastatur wird das Werkzeug zum Verschieben ausgewählt. Um den Text erneut zu bearbeiten, muss lediglich das Textwerkzeug ausgewählt und auf den entsprechenden Text geklickt werden.
Durch Edit -> Free Transform oder STRG + T auf der Tastatur lässt sich der Text drehen und verzerren. Bestätigt wird mit der Entertaste!
Schritt 3: Bild speichern
Es ist wichtig, dass das Bild als PNG oder GIF Datei gespeichert wird. Das JPEG Format unterstütz nur 3 Farbkanäle: Rot, Grün und Blau. In unserem Bild ist jetzt allerdings ein vierter: Transparenz. Dafür verwendet man PNG. GIF ist das Format für animierte Grafiken und unterstützt ebenso Transparenz.
Bild speichern mit Gimp:
File -> Export oder STRG + E auf der Tastatur öffnet den Speicherdialog. Hier wird jetzt einfach ein Pfad ausgewählt. Dann einen Dateinamen eingeben und unbedingt an die Endung .png denken!
Bild speichern mit Photoshop:
File -> Save oder STRG + S auf der Tastatur öffnet den Speicherdialog. Hier wird ein Pfad gewählt und ein Dateiname eingegeben. Unter dem Dateinamen muss noch der Typ auf PNG gestellt werden!
Das wars
Sollten Fragen zur Bedienung offen sein immer heraus damit.
[Reserviert]
[Reserviert]
Hej!
Ich wurde in letzter Zeit häufig gefragt, wie es sich eigentlich mit Javascript und Objektorientierung verhält. Javascript hat nicht wirklich feste Programmierparadigma (Programmierstil). Das gilt auch für Objektorientierte Programmierung. Durch diese fehlenden Vorgaben muss man sich das alles selbst herleiten. Das ist für bereits in anderen Sprachen mit festen Paradigma erfahrene Anwender anfangs extrem schwierig und für absolute Programmieranfänger schlciht unmöglich. Daher möchte ich hier ein wenig Licht ins Dunkel bringen und nebenbei auch die ein oder andere Parallele zu anderen Skript- und Programmiersprachen ziehen.
Falls Fragen oder Unklarheiten auftauchen ist jeder herzlich eingeladen sie hier zu posten.
Absätze, die sich eher an Anfänger richten, werde ich durch ein vorangestelltes "Grundlagen:" markieren, damit sie von erfahreneren Nutzern, falls gewünscht, übersprungen werden können.
Was solltest DU bereits wissen?
Grundlegendes Verständnis für Javascript sollte vorhanden sein. Das bezieht vor allem Folgendes ein:
Falls etwas unbekannt ist, kann über das Fragezeichen dahinter fehlendes Wissen aufgeholt werden.
1.0 Was ist eine Klasse?
Grundlagen: Eine Klasse kann als eine Sammlung von verschiedenen Variablen und Funktionen, die diese verarbeiten, bezeichnet werden. Da es in Javascript keine offensichtlichen Variablentypen gibt, ist dies auf den ersten Blick umso undurchsichtiger. In Sprachen mit starker Typisierung (das heißt, jeder Variable muss ein Typ zugewiesen werden und es können nur Inhalte dieses Typs erfasst werden) ist das Ganze etwas ersichtlicher.
Eine Klasse beinhaltet wie bereits gesagt verschiedene Variablen, welche man Eigenschaften nennt, und verschiedene Funktionen, welche Methoden genannt werden. Hier findet sich ein Beispiel einer Klasse (keine Programmierkenntnisse erforderlich).
In den meisten Sprachen gibt es ein spezielles Keyword, mit dem eine Klasse angelegt werden kann. Hier z. B. in PHP:
Oder in C++:
In Javascript entfällt dieses class-Keyword jedoch. Grundlegend ist jede Javascript Funktion auch eine Klasse.
Ob dieser Codeabschnitt als Klasse oder Funktion behandelt wird, entscheidet sich jetzt im Aufruf. Durch das zuweisen zu einer Variable mit dem Keyword new (für: neue Instanz anlegen) legt Javascript eine neue Instanz an. Eine Instanz ist eine Kopie der Klasse mit allen Eigenschaften und Methoden, die unabhängig von anderen Instanzen ist.
// Einfacher Funktionsaufruf
Person();
// Instanziierung der Klasse "Person"
var Klaus = new Person();
1.1 Wie füge ich nun Eigenschaften hinzu?
Eigenschaften sind schon vorhanden. Sowohl this.name, als auch this.age sind Eigenschaften. Das this-Keyword wird später erklärt.
1.2 Konstruktor?
Grundlagen: Der Konstruktor ist eine spezielle Funktion, welche immer zusammen mit der Instanziierung der Klasse aufgerufen wird. Dort werden in der Regel initiale Einstellungen für die Klasse getroffen. Ebenso lassen sich bereits Parameter übergeben, um die erstellten Eigenschaften mit Inhalt zu füllen:
Beim Instanziieren der Klasse können jetzt Werte übergeben werden:
An dieser Stelle sei erwähnt, dass es in Javascript keine Möglichkeit gibt sinnvoll Destruktoren zu setzen.
1.3 Weitere Funktionen hinzufügen?
Das geht genau so einfach, wie Eigenschaften erstellen:
function Person(name)
{
this.name = name;
this.getName = function()
{
return this.name;
}
}
Die Funktion kann nun aufgerufen werden und gibt den Namen zurück:
// Instanziierung der Klasse "Person"
var Klaus = new Person("Klaus");
console.log(Klaus.getName());
1.4 Private Eigenschaften und Methoden?
Private Eigenschaften und Methoden sind solche, die außerhalb der Klasse nicht aufgerufen werden können. Leider unterstützt Javascript keine Paradigma hierfür.
Über das var-Keyword lässt sich ein Workaround erstellen. Das ist jedoch aufwändig und rentiert sich eher nicht. Hier gilt die klare Empfehlung zu verzichten.
Einsteiger in die Objektorientierung können an der Stelle aufatmen, private, public und protected sind in den meisten Objektorientierten Sprachen jedoch extrem wichtig
und wenn man sie gewohnt ist, fehlen sie einem schnell.
1.5 Prototype?
Hier haben besonders Entwickler Schwierigkeiten, die bereits andere Programmiersprachen gewohnt sind. Jede Funktion (und damit jede Klasse) hat einen Prototypen. Darin werden alle Eigenschaften und Methoden gespeichert. Wenn mittels this eine Eigenschaft oder Methode initiiert wird, landet diese im Prototypen.
Das ist zum Beispiel nützlich wenn man der Übersicht halber eine Methode nicht im Konstruktor definieren möchte:
function Person(name)
{
this.name = name;
}
Person.prototype.getName = function()
{
return this.name;
}
Alles anzeigen
So lässt sich enorm viel Übersicht gewinnen.
Achtung! Private Eigenschaften und Methoden werden nicht im Prototypen erfasst!
1.6 Das wars?
Nein. Aber fürs Erste soll es das gewesen sein. In Kürze werde ich noch über Vererbung, also die Kommunikation zwischen verschiedenen Klassen, schreiben. Außerdem
werde ich Schritt für Schritt eine Klasse aufbauen und erklären. Das Ganze im Bezug auf ein sinnvolles Beispiel im Alltag.
Ich hoffe ich konnte dem ein oder anderen ein wenig Licht ins Dunkel bringen.
PS.: Yay, 2k
Wenn du nichts speichern und später wieder aufrufen möchtest ist das recht einfach umzusetzen. Wenn du das jedoch möchtest, brauchst du zusätzlich PHP und eventuell eine SQL Datenbank.
Ich habe das mal rein von der Programmlogik umgesetzt. Für learning by doing schlage ich vor du schaust es dir an und fragst nach sobald du etwas nicht verstehst. Bis ins Detail erklären ist leider zu aufwändig.
Im Großen und Ganzen gibt es 3 große Funktionen: Eine Reihe hinzufügen, die Summe ermitteln und die Summe ausgeben.
Was dir eventuell nicht bekannt vorkommt ist die Art, wie ich Funktionen definiert habe. Javascript Funktionen sind im Grunde Klassen. In Zeile 1 definiere ich die Funktion FinanceCalculator, in Zeile 134 ertselle ich mittels dem new Keyword eine Instanz der Klasse. Mittels FinanceCalculator.prototype.funktionsname fügt man zu dieser Klasse neue Funktionen hinzu, die dann mithilfe der in Zeile 134 erstellten Variable, oder innerhalb der Klasse mit dem this Keyword aufgerufen werden.
Wie gesagt: Falls Fragen auftauchen, raus damit.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Finanzrechner</title>
<style>
table {
border-collapse: collapse;
}
td, th {
padding: 3px;
}
tr:last-child {
font-weight: bold;
}
#sum {
text-align: right;
}
#add {
text-align: center;
cursor: pointer;
}
input[name^=value]{
text-align: right;
}
</style>
<script src="finanzrechner.js"></script>
</head>
<body>
<table border="1">
<tr>
<th>Umsatz</th>
<th>Betrag</th>
<th title="Ertrag">E</th>
<th title="Aufwand">A</th>
</tr>
<tr>
<td>Übertrag</td>
<td colspan="3">
<input type="text" name="transfer">
</td>
</tr>
<tr id="lastRow">
<td id="sum" colspan="2">0,00</td>
<td id="add" colspan="2">+</td>
</tr>
</table>
<input type="button" value="Drucken" id="print">
</body>
</html>
Alles anzeigen
var FinanceCalculator = function(sum, add)
{
this.transfer = document.getElementsByName("transfer")[0];
this.sum = this.clearNumber(this.transfer.value);
this.count = 0;
this.values = Array();
this.lastRow = document.getElementById("lastRow");
this.result = document.getElementById(sum);
document.getElementById(add).addEventListener("click", function () {
this.addRow();
}.bind(this));
this.transfer.addEventListener("keyup", function () {
this.calculateSum();
}.bind(this));
this.addRow();
}
FinanceCalculator.prototype.createElement = function(htmlName, attributes)
{
var element = document.createElement(htmlName);
if("undefined" === typeof attributes)
return element;
for(var key in attributes)
{
if(!attributes.hasOwnProperty(key))
continue;
element.setAttribute(key, attributes[key]);
}
return element;
}
FinanceCalculator.prototype.insertRow = function(element, target)
{
target.parentNode.insertBefore(element, target);
return;
}
FinanceCalculator.prototype.addRow = function()
{
var input, td, tr = this.createElement("tr");
td = this.createElement("td");
input = this.createElement("input", {type:"text", name:"description" + this.count});
td.appendChild(input);
tr.appendChild(td);
td = this.createElement("td");
input = this.createElement("input", {type:"text", name:"value" + this.count});
input.addEventListener("keyup", function () {
this.calculateSum();
}.bind(this));
td.appendChild(input);
tr.appendChild(td);
td = this.createElement("td");
input = this.createElement("input", {type:"radio", name:"gain" + this.count, value:true, checked:"checked"});
input.addEventListener("change", function () {
this.calculateSum();
}.bind(this));
td.appendChild(input);
tr.appendChild(td);
td = this.createElement("td");
input = this.createElement("input", {type:"radio", name:"gain" + this.count, value:false});
input.addEventListener("change", function () {
this.calculateSum();
}.bind(this));
td.appendChild(input);
tr.appendChild(td);
this.values.push(
Array
(
tr.getElementsByTagName("input")[1],
tr.getElementsByTagName("input")[2]
)
);
this.insertRow(tr, this.lastRow);
this.count++;
return;
}
FinanceCalculator.prototype.clearNumber = function(val)
{
if(!val)
return 0;
val = val.replace(",", ".").replace(/[^\d.-]/g, '');
return parseFloat(val);
}
FinanceCalculator.prototype.calculateSum = function()
{
this.sum = this.clearNumber(this.transfer.value);
for(var i = 0; i < this.values.length; i++)
{
var amount = this.clearNumber(this.values[i][0].value);
if(this.values[i][1].checked)
this.sum += amount;
else
this.sum -= amount;
}
if(isNaN(this.sum))
this.sum = this.transfer.value;
this.sum = this.sum.toFixed(2);
this.printResult();
return;
}
FinanceCalculator.prototype.printResult = function()
{
if(this.sum < 0)
this.result.style.color = "red";
else
this.result.style.color = "black";
this.result.innerHTML = this.sum.replace(".", ",");
return;
}
window.addEventListener("load", function () {
var FC = new FinanceCalculator("sum", "add");
document.getElementById("print").addEventListener("click", function () {
window.print();
});
});
Alles anzeigen
Hallo!
Wenn du mit Canvas arbeiten möchtest (was ich nur empfehlen kann), dann kann ich dir hier einige Tipps mit an die Hand geben.
Achtung: Grafische Effekte, die mit CSS erzielt werden, sind um ein vielfaches aufwändiger zu berechnen als Canvas. Gerade als mobile Lösung für Animationen kann ich aufgrund der Vielzahl an Geräten nur Canvas empfehlen.
Um es dir einfacher zu machen, solltest du alle Maße innerhalb des Bildes, welches gezeichnet werden soll, in Abhängigkeit der Größe des Canvas berechnen. Dazu legst du am Betsen erstmal ein Seitenverhältnis fest. In meinem Beispiel nehme ich mal 1:1. Das heißt, das Bild ist genau so breit wie hoch. Die Größe ist dabei erst einmal unrelevant:
Zum testen noch ein wenig Farbe:
Jetzt wird im Browser ein dunkelgrauer Kasten angezeigt.
Als nächstes mittels Javascript den Kontext holen:
var canvas = document.getElementsByTagName("canvas")[0];
var ctx = canvas.getContext("2d");
Und nun ganz wichtig. Die Dimension des Canvas auslesen:
Jetzt sollten alle Größen in Abhängigkeit dieser Werte gebildet werden. Als Beispiel nehme ich einfach mal einen hellgrauen Quader und einen roten Kreis.
Der Quader soll 10% Abstand nach oben und genau den selben Abstand nach links haben. Außerdem soll er genau 20% der Höhe des Canvas als Maße annehmen. Ganz wichtig: Immer abrunden! Wenn Canvas mit ungerundeten Fließkommazahlen arbeitet erhält man unschöne Nebeneffekte wie z. B. unterschiedliche Abstände trotz gleicher Größe oder unscharfe Kanten. Wenn man aufrundet, sind Elemente eventuell nicht mehr sichtbar, da sie über den Rand hinaus gehen.
Die Berechnung könnte also so aussehen:
var cubeDimension = {
size: Math.floor(canvasDimension.height*.2),
x: Math.floor(canvasDimension.height*.1),
y: Math.floor(canvasDimension.height*.1)
}
Dann nur noch Farbe setzen und zeichnen:
ctx.fillStyle = "#999999";
ctx.fillRect(cubeDimension.x, cubeDimension.y, cubeDimension.size, cubeDimension.size);
Der Radius des Kreises soll 10% der Höhe, der Abstand nach rechts 10% und der Abstand nach unten 15% betragen. Die Koordinaten werden in der arc-Funktion für das Zentrum des Kreisbogens angegeben, das muss beachtet werden. Die Berechnung könnte so aussehen:
var circleDimension = {
radius: Math.floor(canvasDimension.height*.1),
x: Math.floor(canvasDimension.height*.9 - canvasDimension.height*.1),
y: Math.floor(canvasDimension.height*.85 - canvasDimension.height*.1)
}
Und dann noch zeichnen:
ctx.fillStyle = "#ff0000";
ctx.beginPath();
ctx.arc(circleDimension.x, circleDimension.y, circleDimension.radius, 0, Math.PI*2);
ctx.fill();
Es ist sicher kein beeindruckendes Gemälde, jedoch kommt nun der eigentliche Knackpunkt. Wenn die Größe des Canvas verändert wird, ändert sich der Inhalt proportional mit:
Siehe Bilder im Anhang oder einfach hier selber ausprobieren.
Animieren lässt sich ein Canvas auch wunderbar mittels der requestAnimationFrame-Funktion.
Canvas kann besonders bei trignometrischen Funktionen wirklich kompliziert werden, da braucht es ein wenig sich reinzuarbeiten. Es lohnt aber auf jeden Fall und hier im Forum erhältst du jederzeit alle Hilfe, die du benötigst.
Ich hoffe ich konnte ein wenig helfen.
html-seminar.de/woltlab/attachment/931/html-seminar.de/woltlab/attachment/932/
Kein Thema
Es können nur sichtbare Elemente geklickt werden. Das label-Element im Link verdeckt den Link (zumindest an der Stelle, wo es sich befindet) und blockiert so diesen klickbaren Bereich.
<body>
<a href="test.htm" target="_blank">Blog
<label for="toggle-submenu">Ich löse den Link nicht aus</label>
</a>
<input id="toggle-submenu" type="checkbox">
</body>
Etwas leichter nachzuvollziehen ist das, wenn man Hintergrundfarben setzt:
Man sieht den blauen Hintergrund des Links nicht hinter dem roten Hintergrund des label-Elementes und man kann nur sichtbare Elemente klicken.
Ein anderes Beispiel dazu:
* {
margin: 0;
padding: 0;
}
div {
position: absolute;
top: 0;
left: 10px;
width: 100px;
height: 100px;
background: red;
}
Alles anzeigen
Der Link ist nicht mehr komplett sichtbar und nur der sichtbare Teil ist klickbar.
Du könntest das label-Element innerhalb des a-Elements platzieren:
<li>
<a href="#">Blog
<label for="toggle-submenu" class="submenu-button">
<img src="http://img.jr-cologne.bplaced.net/submenu-button.svg">
</label>
</a>
<input id="toggle-submenu" class="toggle" type="checkbox">
<!-- [...] -->
Dann natürlich noch das a-Element relativ positionieren.
Ich kann leider nicht nachvollziehen, worum genau es geht. Um welchen Punkt geht es? Was soll er machen und was macht er? Meinst du horizontal oder vertikal? Meinst du die Ansicht für schmale Auflösung?
Mit float werden main und aside aus dem Dokumentenfluß genommen und andere Elemente können deshalb nicht mehr auf sie reagieren.
Können sie schon. Man muss es ihnen nur mitteilen (clear und eventuell overflow).
Das kann imagecopyresampled
Funktioniert fast genau so wie imagecopy, außer das nun zusätzlich die gewünschten Maße und Koordinaten angegeben werden. Die Koordinaten bleiben bei einem einfachen resize 0 und 0, die Breite und Höhe ($newWidth, $newHeight) kannst du mit PHP dynamisch generieren lassen oder mit ins Formular einbauen.
Für deine Fragen sind wir hier.
// Leider verliert der Text immer die Zeilenumbrüche beim kopieren, jemand einen Tipp? Arbeite mit Notepad++ //
Das Problem ist uns bekannt. Welches Betriebssystem in welcher Version benutzt du? 32 oder 64 Bit?
Hallo.
Du brauchst auf jeden Fall PHP. Wenn dir das HTML-Seminar gefallen hat, kann ich dir den PHP-Kurs empfehlen. Der ist auch von Axel Pratzner und vermittelt dir Grundkenntnisse.
Die für dich interessanten Themen sind da besonders Formulare, Sessions und Datenbanken. Hier findest du auch ein Modell einer Zugangsabfrage.
Dann brauchst du eine Benutzerverwaltung. Dafür hat wolf: hier im Forum mal ein Beispiel geschrieben, das findest du hier. Am Ende eine Mail an ausgewählte Nutzer verschicken ist kein Problem mehr, dafür gibt es die php mail-Funktion, welche mit laufendem Mailserver in der Lage ist E-mails zu versenden.
Du solltest dir das Wissen selbst aneignen. Das ist innerhalb von 1-2 Wochen erledigt mit de nötigen Ehrgeiz (den du zu haben scheinst).
Wenn dir das zu aufwändig ist, kannst du dich alternativ natürlich auch umhören, ob dir jemand zur Hand gehen möchte.
HTML-Seminar.de - mit Videos zum schnellen Lernen, wie man eine Website selbst erstellt.