Johannes Kinast https://go-around.de/ Durchstarten Thu, 30 Jun 2022 10:11:07 +0000 de hourly 1 https://wordpress.org/?v=6.8.3 https://go-around.de/app/uploads/sites/6/2019/08/cropped-profilbild-2-32x32.jpg Johannes Kinast https://go-around.de/ 32 32 Private GitHub npm Packages im GitHub Actions Workflow verwenden https://go-around.de/blog/private-github-npm-packages-github-actions/ https://go-around.de/blog/private-github-npm-packages-github-actions/#respond Thu, 30 Jun 2022 10:11:06 +0000 https://go-around.de/?p=716 GitHub bietet mit GitHub Packages eine limitiert kostenfreie Alternative zu den sonst kostenpflichtigen privaten npm Packages an. Allerdings habe ich lange nach einem Weg suchen müssen, private GitHub Packages in GitHub Actions zu verwenden.

npm login kann man nicht so einfach ausführen, weil der Personal access token eingegeben werden muss und nicht über einen Parameter übergeben werden, kann und der secrets.GITHUB_TOKEN nicht ausreicht, um private GitHub Packages über npm install zu laden.

Meine Lösung für das Problem:

1. Eigene .npmrc-Datei für GitHub Actions

Als Erstes müssen wir für GitHub Actions eine eigene .npmrc-Datei erstellen, damit sich die nicht mit unserer bestehenden .npmrc-Datei beißt, nennen wir sie .npmrc.githubactions und benennen sie später um, wenn wir sie benötigen.

Die .npmrc-Datei sorgt dafür, dass npm für euren privaten Scope, meiner lautet z.B. @goaround nicht wie sonst üblich mit registry.npmjs.org spricht, sondern mit npm.pkg.github.com. Dabei autorisieren wir uns mit unserem authToken, den wir im zweiten Schritt erstellen.

Kopiert folgendes Snippet in eure .npmrc.githubactions und ersetzt myownscope durch euren eigenen GitHub-Scope:

@myownscope:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

2. GitHub Action modifizieren

In eurer yml-Datei für den Workflow (findet ihr in /.github/workflows) müsst ihr jetzt einige Modifikationen vornehmen, damit die .npmrc.githubactions bei npm install verwendet und die Variable ${GITHUB_TOKEN} gesetzt wird.

Bevor ihr npm install ausführt, überschreibt ihr mit .npmrc.githubactions die bestehende .npmrc und zusätzlich definiert ihr für diesen Schritt noch die Variable GITHUB_TOKEN mit eurem PERSONAL_GITHUB_TOKEN:

- name: Install npm dependencies
  run: |
    mv .npmrc.githubactions .npmrc
    npm install --silent
  env:
    GITHUB_TOKEN: ${{secrets.PERSONAL_GITHUB_TOKEN}}

3. Personal Access Token erstellen

Damit das Ganze auch funktioniert, müssen wir noch einen Personal access token mit den entsprechenden Berechtigungen erstellen. Geht dafür auf github.com/settings/tokens und klickt auf Generate new token. Anschließend wählt einen verständlichen Namen z.B. GitHub Actions mypackage, wählt als Expiration am besten No expiration aus (sonst werdet ihr euch irgendwann wundern, warum eurer Workflow nicht mehr durchläuft) und unter Select scopes klicken wir repo und read:packages an.

Mit einem Klick auf Generate token wird der Token erstellt und euch einmalig angezeigt. Kopiert ihn und geht zurück in die GitHub Repository und fügt ihn unter SettingsSecuritySecretsActions als Repository Secret unter dem Namen PERSONAL_GITHUB_TOKEN hinzu:

Fertig

Anschließend sollte euer Workflow durchlaufen und auch das bei GitHub Packages abgelegte private Paket installieren können.

]]>
https://go-around.de/blog/private-github-npm-packages-github-actions/feed/ 0
Ist Tailwind CSS eine gute Idee für WordPress Themes & Plugins? https://go-around.de/blog/tailwind-css-wordpress/ https://go-around.de/blog/tailwind-css-wordpress/#comments Fri, 21 Jan 2022 09:10:03 +0000 https://go-around.de/?p=627 Tailwind CSS hat sich in den letzten Jahren von einem belächelten CSS-Framework zu einem echten Schwergewicht entwickelt. Der Grund dafür ist einfach: Es nimmt euch komplett die Frage ab, wie ihr eure CSS-Klassen benennt: gar nicht!

Statt euch für jedes Element eures Designs eine oder mehrere Klassennamen auszudenken und die Klasse dann in eurem Stylesheet zu definieren, definiert ihr bei Tailwind den Style direkt über einfach zu merkende CSS-Klassen im HTML-Markup, z.B. block p-2 mx-3 mt-3 bg-gray-900 hover:bg-gray-700 text-white cursor-pointer. Aufgelöst sieht der genutzte Teil des Stylesheets wie folgt aus:

.block {
    display: block;
}
.p-2 {
    padding: 0.5rem;
}
@media (min-width: 1280px) {
  .xl\:p-4 {
    padding: 1rem;
  }
}
.mx-3 {
    margin-left: 0.75rem;
    margin-right: 0.75rem;
}
.mt-3 {
    margin-top: 0.75rem;
}
.bg-gray-900 {
    background-color: rgb(17, 24, 39);
}
.hover\:bg-gray-700:hover {
    background-color: rgb(55, 65, 81);
}
.text-white {
    color: rgb(255, 255, 255);
}
.cursor-pointer {
    cursor: pointer;
}

Sogar Media Queries und Hover-Zustände lassen sich problemlos mit den Tailwind-Klassen schnell und einfach anwenden und theoretisch könnt ihr euer Design komplett im HTML schreiben.

Wie sich das anfühlt, davon vermittelt die Tailwind-Website ein gutes Gefühl oder ihr tobt euch auf dem Spielplatz aus.

Update

Mittlerweile gibt es Tailwind CSS in der Version 3.0 und damit eine große (und positive Änderung): Just-in-Time-Engine als Standard zur Erzeugung des Stylesheets. Vorher wurden alle möglichen CSS-Klassen in das Stylesheet geschrieben und man sollte (eher musste) mit PurgeCSS alle nicht benutzen Klassen für die Produktivitätsumgebung entfernen. Mit JIT ist es jetzt genau umgekehrt. Es werden nur die Klassen in eure Stylesheet geschrieben, die auch gefunden wurden. Außerdem kann Tailwind jetzt on the fly auch Klassen erstellen, die man vorher in der Konfigurationsdatei erst eintragen musste, z.B. w-[1050px] für width: 1050px;

Außerdem gibt es jetzt einen Play CDN mit dem ihr Tailwind einfach testen könnt und eine Tailwind CLI die das Tooling deutlich vereinfacht.

Mein Tailwind-Lebenslauf

Ich nutze Tailwind CSS bereits seit Anfang 2018 (Version 0.3.0, mittlerweile gibt es Version 2.0 3.0) nachdem ich darüber einen Podcast gehört habe und bis heute hatte ich keinen Grund mich nach einem anderen CSS Framework umzuschauen. Das hat(te) folgende Gründe:

Ich sehe mich mehr als Entwickler und weniger als Designer und fand es deswegen immer extrem umständlich mir Klassennamen auszudenken, an die man sich auch 3 Monate später noch erinnert (das Problem habe ich grundsätzlich mit Namen) und so auch wirklich wiederverwendet. Meistens denkt man sich dann doch eher eine neue CSS-Klasse aus, als das eigene toll definierte Design System zu verwenden.

Eigentlich will ich mich auch gar nicht so viel mit Design beschäftigen. Deswegen habe ich früher auch Bootstrap oder Bulma ausprobiert. Das Problem ist einfach nur: Die Website sieht aus wie geschätzt 50% des Webs und das hat mir noch nie gefallen. Ich konnte zwar einigermaßen gut mit CSS umgehen und eigentlich schreibe ich auch gerne CSS, aber bestehende Klassen zu überschreiben, um den Stil anzupassen, hat mich schon immer genervt (vor allem bei WordPress Themes).

Ich kann also einigermaßen gut mit CSS umgehen, kann mir keine Namen ausdenken und vor allem merken und habe keine Lust auf das Standarddesign von Bootstrap oder Bulma. Tailwind war da der perfekte Kompromiss: Ich muss selber CSS schreiben, bin auf eine begrenzte Anzahl gut zu merkender Klassennamen limitiert und muss mir vor allem keine eignen Namen ausdenken.

Gleichzeitig habe ich bei Tailwind nicht das Gefühl ich verlerne CSS. Im Gegenteil. Ich bin in den letzten drei Jahren deutlich sicherer im Umgang mit CSS geworden und habe auch kein Problem mal eine Klasse wirklich zu definieren und zu stylen. Der Grund dafür ist die Dokumentation von Tailwind CSS. Diese ist wirklich ausgezeichnet und erklärt sehr anschaulich wie alle CSS Eigenschaften funktionieren. Hier zum Beispiel am Beispiel von justify-content:

Auszug aus der Tailwind Dokumentation zu justify-content für Flex(box)

Ein weiterer Grund, warum ich Tailwind liebe, ist, dass es mir alle Freiheiten lässt, mich aber gleichzeitig einschränkt. Zum Beispiel was die Nutzung von Paddings und Margins angeht. Früher hatte ich Abstände in Form von 1px, 2px, 3px, 5px, 8px, 9px, 10px …, 99px in meinem Stylesheet, was dazu führt, dass das Design irgendwann vollkommen inkonsistent wirkt. Tailwind limitiert mich hier durch die Klassen und gibt mir eine ausreichende, aber nicht überforderte, Auswahl in festen Abständen 0.25rem, 0.5rem, 0.75rem, 1rem… vor. Damit komme ich deutlich besser klar. Zur Not kann ich aber auch mir eine CSS-Klasse wie w-[1050px] = width: 1050px; erstellen lassen, wenn ich sie brauche.
Das Gleiche gilt für Farben. Hier liefert Tailwind eine vordefinierte Farbpalette mit Abstufungen, an die man sich halten kann, aber auch nach Belieben verändern oder erweitern kann. Auch das führt dazu, dass das eigene Design deutlich konsistenter wirkt.

Auch wenn ich Tailwind mal nicht verwende, schaue ich alle CSS-Eigenschaften in der Tailwind Dokumentation nach. Selbst wenn ihr euch gegen den Einsatz von Tailwind entscheidet, kann ich euch das nur empfehlen. Unter Properties stehen ja immer die wahren CSS-Eigenschaften der Tailwind-Klasse.

Was gegen Tailwind in WordPress Themes & Plugins spricht

Jetzt aber genug mit den Lobeshymnen auf Tailwind. Die Frage dieses Artikels war ja: Ist es eine gute Idee Tailwind für ein WordPress Theme oder Plugin zu verwenden und was muss ich beachten und ggf. anders machen?

Wie immer lautet die grundsätzliche Antwort darauf: Es kommt darauf an! Tailwind ist keine eierlegende Wollmilchsau!

Deswegen erst einmal ein paar Punkte die dagegen sprechen:

Theme HTML Markup ändert sich oft

Da ihr euer Style direkt im HTML Markup definiert, ändert sich das Markup regelmäßig. Das führt vorwiegend in Kombination mit Child-Themes zu großen Problemen. Überschreibt ihr ein Template im Child-Theme und ändert Klassen im Parent-Theme, müsst ihr auch daran denken, das Child-Theme anzupassen.

Wird euer Theme nicht nur von euch genutzt, z.B. ihr bietet es in der WordPress.org Theme Repository an, ist Tailwind meiner Meinung nach der falsche Weg. Ihr könnt aber trotzdem die Tailwind Klassen in eurem Stylesheet mit der @apply-Regel nutzen.

Ich kann hier übrigens auch in jeder Hinsicht die Kritik an Tailwind verstehen. In der Theorie sollte HTML und CSS getrennt werden, aber die Realität in der Praxis sieht meiner Meinung nach meistens ganz anders aus. Alleine um CSS Flexbox und Grid richtig nutzen zu können, muss man das HTML Markup entsprechend designen und zu oft schreibt man am Ende CSS-Selektoren, die bis ins Unendliche verschachtelt und einfach nicht wiederverwendbar sind.

Block Markup ändert sich oft

In Plugins halten ja immer mehr Gutenberg Blöcke Einzug. Hier hat man die Wahl zwischen clientseitig mit JavaScript gerenderten Blöcke, d.h. das Markup inkl. ggf. der Tailwind-Klassen wird so in der Datenbank gespeichert, oder serverseitig gerenderten Blöcke, wo i.d.R. nur die Attribute in der Datenbank gespeichert werden.

Für clientseitig gerenderte Blöcke kann ich nur von Tailwind abraten. Wenn ihr nicht direkt den perfekten Style hinlegt und ihn nachträglich ändern wollt, wird jeder alte Block im Block Editor eine Fehlermeldung anzeigen und muss wiederhergestellt werden. Außerdem müsst ihr jeden Block im Editor per Hand updaten, damit die Tailwind-Klassen übernommen werden. Glaubt mir: Das wollt ihr nicht.
Hier ist es definitiv sinnvoll sich einmal CSS-Klassen auszudenken und im Stylesheet den Style zu definieren. Ihr könnt aber auch hier wieder @apply nutzen.

Bei serverseitig gerenderten Blöcke sieht es wieder anders aus. Hier ist es kein Problem den HTML Elementen direkt Tailwind-Klassen zu verpassen. Ändert ihr euren PHP-Code, wird die Änderung ja direkt von allen bestehenden Blöcken ausgeliefert.

Mit WordPress 5.9 kommt voraussichtlich das Full Site Editing in den Core von WordPress. Bisher habe ich mich noch nicht damit auseinandergesetzt, was das für den Einsatz von TailwindCSS bedeutet. Soweit ich weiß kann man aber auch dort direkt die HTML-Dateien im Theme-Ordner ablegen und so voraussichtlich auch mit Tailwind gestalten.

Übrigens könnt ihr bei fast jedem Block im Block Editor unter SidebarBlockErweitertZusätzliche CSS-Klasse(n) Tailwind-CSS-Klassen eingeben und so verwenden. Ihr müsst aber sicherstellen, dass die verwendeten Klassen auch in eurem Stylesheet landen (siehe diesen Tipp).

Was man bedenken sollte

Zusätzlich gibt es einige Punkte, die ihr vor eurer Einsatz in einem WordPress Theme oder Plugin bedenken solltet:

CSS Klassen von WordPress

Wenn ihr ein Theme designt, stylt ihr nicht nur euer eigenes HTML Markup, sondern auch die Menüs, Widgets, Kommentare … von WordPress. Dieses haben fest definierte CSS Klassen, die sich nicht so einfach ändern lassen. Hier müsst ihr also zwangsläufig das Design über euer Stylesheet regeln und Tailwind verliert zumindest einen Teil der Vorteile. Die Tailwind Klassen könnt ihr aber trotzdem zum stylen dank @apply nutzen.

Tooling

Um Tailwind auszuprobieren, könnt ihr zwar einfach einmal Tailwind über einen CDN laden. Hier funktioniert sogar die JIT Engine im Hintergrund! Allerdings ist das nichts, was ihr für euer Theme oder Plugin wirklich bei jedem Seitenaufruf ausliefern wollt.

Ihr müsst also zwangsläufig mit npm, Webpack (hier vereinfacht euch Laravel Mix sehr das Leben) und PostCSS beschäftigen, um das volle Potenzial von Tailwind auszunutzen und eure .css-Datei für die Produktionsumgebung zu erstellen (i.d.R. deutlich unter 100 kb). Seit 3.0 gibt es auch ein eigene Tailwind CLI, die den Start vereinfacht.

Für ein Theme lohnt sich der Aufwand (und der Wartungsaufwand) definitiv, aber nicht für jedes kleine Plugin, wo man nur ein paar Zeilen CSS schreiben muss, um z.B. seinen Block zu stylen.

Ich habe viele private Plugins für Travel-Dealz geschrieben, die nicht öffentlich zugänglich sind und liefere i.d.R. den gesamten Style über das Theme aus und muss deswegen nur einmal das ganze Tooling aufsetzen.

Lösungen

Es gibt einige Probleme, die man durch den Einsatz von Tailwind zwangsläufig haben wird, aber dafür gibt es auch gute Lösungen:

@apply

Nicht immer kann man die Tailwind-Klassen direkt im HTML Markup anbringen, auch wenn es der bevorzugte Weg ist. An dieser Stelle kommt die @apply-Regel in Spiel. @apply ist eigentlich bisher ein inoffizieller W3C Vorschlag und soll dazu dienen, CSS-Variablen als wiederverwendbare Bündel (Mixins) zu definieren, die man dann über die @apply-Regel auf CSS-Regeln anwenden kann.

Bei Tailwind dient @apply dazu die Tailwind-Klassen auf CSS-Regeln im eigenen Stylesheet anzuwenden, z.B.

/* Input */
.btn {
  @apply py-2 p-4;
}

Da es für @apply bisher eh keine Unterstützung von den Browsern gibt, wird das ganze mithilfe von PostCSS in reguläres CSS übersetzt:

/* Output */
.btn {
  padding: 1rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}

Mit diesem Trick könnt ihr ganz normales CSS schreiben, aber trotzdem die „Kurzbefehle“ von Tailwind verwenden. Ihr könnt in @apply seit Tailwind 2.0 sogar die ganz normalen Tailwind-Klassen für Media Queries, z.B. xl:p-4, verwenden.

Just-in-Time Engine

Mit Tailwind 2.1 wurden bereits die Just-in-Time Engine als Option eingeführt und mit 3.0 zum Standard. JIT ersetzt PurgeCSS, an dem bisher kein Weg vorbeigeführt hat. Damit eurer Stylesheet am Ende nicht mehrere MB groß ist, müssen ungenutzte Klassen entfernt werden. Bisher hat PurgeCSS das am Ende gemacht. Mit der JIT Engine werden jetzt nur noch die benötigten Klassen überhaupt erzeugt und es öffnet auch viele andere Möglichkeiten der Erweiterung.

Das ganze funktioniert, indem ihr eure Datei (PHP, HTML, JS…) nach CSS-Klassennamen gescannt werden. Anschließend erzeugt TailwindCSS die entsprechenden CSS-Klassen. Dafür müsst ihr einmal in eurer Konfigurationsdatei tailwind.config.js unter content die Ordner & Dateien definieren, die überwacht werden sollen. Bei mir sieht das z.B. wie folgt aus:

module.exports = {
	content: [
		'./*.php',
		'./functions/*.php',
		'./templates/*.php',
		'./purge-templates/*.html',
	]
}

Dank JIT könnt ihr auch Klassen erzeugen, die eigentlich so von Tailwind gar nicht definiert sind, z.B. w-[1050px] = width: 1050px;.

Statt alle Tailwind-Klassen, die rund 3 mb groß sind (3020.9 KiB), reduziert die JIT Engine meine Stylesheet für diesen Blog z.B. auf 44 KiB.

Hinzu kommt noch, dass in Tailwind-Klassen viele Zeichenabfolgen sich vielfach wiederholen, was dazu führt, dass sich die Datei außerordentlich gut komprimieren lässt. So wird aus 44 KiB mithilfe von Gzip 9 KiB, die nur übertragen werden müssen.

Tipp

Wenn ihr Tailwind auch außerhalb eures Themes verwendet, z.B. in einem Plugin wie HTML Forms empfehle ich euch einen Ordner purge-templates in eurem Theme anzulegen und dort einfach das Markup als HTML-Dateien zu hinterlegen. Packt den Ordner unter content in eurer Konfigurationsdatei tailwind.config.js: ./purge-templates/*.html und die JIT Engine erstellt euch die benötigten Dateien.

PurgeCSS (deprecated)

Update

Seit TailwindCSS 3.0 ist die Just-in-Time Engine der Standard und man muss (und sollte) PurgeCSS nicht mehr nutzen. Übrigens hat JIT auch den Vorteil, dass eure mit @apply erzeugten Klassen nicht mehr mit Ingore über ein HTML Template ausgenommen werden müssen.

Ich lasse diesen Abschnitt noch einige Zeit im Artikel für alle, die noch kein Upgrade (das aber zumindest von 2.x einfach ist) durchgeführt haben.

Wenn ihr Tailwind CSS nutzen wollt, führt kein Weg an PurgeCSS vorbei. PurgeCSS sorgt dafür, dass in eurem endgültigen Stylesheet, welches ihr an die Website-Besucher ausliefert, im besten Fall keine nicht benutzen CSS-Klassen enthalten sind.

Wenn ihr npm run production ausführt, rennt PurgeCSS durch alle von euch festgelegten HTML, PHP, JavaScript-Dateien und erstellt eine sehr lange Liste mit möglichen CSS-Klassen, die ihr verwendet habt. Diese Liste wird mit allen von euch und Tailwind definierten CSS-Klassen abgeglichen und nur die Übereinstimmungen landen in dem Stylesheet für eure Produktionsumgebung.

Statt alle Tailwind-Klassen, die rund 3 mb groß sind (3020.9 KiB), reduziert PurgeCSS meine Stylesheet für diesen Blog z.B. auf 44 KiB.

Hinzu kommt noch, dass in Tailwind-Klassen viele Zeichenabfolgen sich sehr oft wiederholen, was dazu führt, dass sich die Datei außerordentlich gut komprimieren lässt. So wird aus 44 KiB mithilfe von Gzip 9 KiB, die nur übertragen werden müssen.

Das Problem an WordPress Themes: Viele CSS-Klassen von WordPress muss man stylen, PurgeCSS wird sie aber im Theme-Ordner nicht finden, weil sie aus dem Core kommen. D.h. die mühevoll gestylten Klassen werden von PurgeCSS entfernt. Es gibt aber mehrere Wege damit umzugehen:

Ignorieren: Alles, was ihr mit einem CSS-Kommentar purgecss ignore verseht, wird von PurgeCSS ignoriert.

/*! purgecss start ignore */
@import './components/comments.css';
/*! purgecss end ignore */

Wichtig ist allerdings den Kommentar mit ! als important zu kennzeichnen, damit es nicht vorher schon beim Minifizieren entfernt wird. PurgeCSS rennt beim Zusammenbauen ganz zum Schluss.

Ignore kann ich euch für alle CSS-Klassen empfehlen, die ihr mit @apply oder regulärem CSS styled.

Purge Templates: Ihr könnt euch in eurem Theme einen Ordner mit HTML-Dateien anlegen, z.B. purge-templates, diesen in content einbeziehen und dort einfach das Markup hineinkopieren.

Mein Ordner mit Templates die nur von PurgeCSS verwendet werden

Ich nutze die Purge Templates hauptsächlich für Komponenten aus anderen Plugins, wo ich direkt Tailwind-Klassen einsetzte und diese nicht im Theme liegen.

Safelisting: Ihr könnt PurgeCSS auch eine Safelist an Klassen mitgeben, die nicht gepurged werden sollen. Hier ist es auch möglich mit Regex zu arbeiten.

Meine Erfahrungen mit Safelisting sind allerdings nicht besonders gut. Man vergisst es dann doch wieder und später die Safelist auszumisten ist ebenfalls deutlich schwieriger, als sinnvoll benannte Dateien in einem Ordner zu löschen. Ich nutze eher die Purge Templates oder das Ignorieren über Kommentare.

Tailwind Ökosystem

Ein Grund, warum ich an Tailwind hängen geblieben bin, ist auf jeden Fall das Ökosystem, was sich um Tailwind entwickelt hat.

  • Tailwind UI: Wer die UI Components von Bootstrap vermisst, findet mit den Tailwind UI Components eine gute (aber kostenpflichtige) Alternative. Die Erschaffer von Tailwind, Adam Wathan und Steve Schoger, haben typische UI-Components mit Tailwind umgesetzt, die sich dank Tailwind auch sehr leicht verändern lassen.
  • Refactoring UI: Ebenfalls von Adam & Steve gibt es ein kostenpflichtiges E-Book, wie man schöne UI’s selber designt und das aus dem Blickwinkel eines Entwicklers.
  • Tailwind Forms: Das TailwindCSS Plugin sorgt für grundlegenden Style von Form-Elementen. Besonders nützlich in Zusammenarbeit mit WordPress, weil man an viele Inputs, z.B. für Kommentare, sonst nicht so einfach herankommt.
  • Tailwind Typography: Ein weiteres Tailwind Plugin, welches für die prose Klasse für eine schöne Typografie sorgt. Nutze ich auch hier im Block, ist mit an eigenen Stellen aber schon zu aggressiv und ich musste eigene Styles überschreiben.

Fazit

Ich bin definitiv ein großer Fan von Tailwind, kann es aber trotzdem nicht uneingeschränkt für den Einsatz mit WordPress empfehlen. Ihr solltet gut abwägen, ob ihr mit den Einschränkungen klarkommt.

Falls ihr Tailwind einfach mal ausprobieren wollt, kann ich euch den Tailwind Spielplatz empfehlen und selbst wenn ihr euch gegen Tailwind entscheidet, kann ich euch trotzdem die Tailwind Dokumentation als grundlegende CSS-Dokumentation ans Herz legen.

]]>
https://go-around.de/blog/tailwind-css-wordpress/feed/ 9
Laravel Tools für WordPress: Lokale Entwicklungsumgebung mit Valet https://go-around.de/blog/laravel-valet-wordpress/ https://go-around.de/blog/laravel-valet-wordpress/#comments Wed, 29 Dec 2021 15:15:02 +0000 https://go-around.de/?p=222 Laravel ist ein PHP-Framework um komplexe Anwendungen zu erstellen und WordPress ein Content Management System um Inhalte zu verwalten und anzuzeigen. Zwar kann man in Laravel auch einen Blog wie bei WordPress umsetzen aber i.d.R. nutzt man Laravel eher für komplexere Anwendungen.

Um Laravel ist aber ein ganzes Ökosystem an nützlichen Tool entstanden, die man auch mit WordPress sehr gut nutzen kann. Meistens handelt es sich dabei um Tools für die Entwicklung z.B. von Plugin & Themes aber auch in anderen Bereichen lassen sie sich nutzen.

In dieser Serie möchte ich euch einige der Tools vorstellen. Den Anfang macht Laravel Valet:

Update

Ursprünglich habe ich den Artikel im April 2020 geschrieben und ich freue mich immer weider, wenn mein Artikel z.B. im WP Sofa Podcast erwähnt wird.

Seitdem hat sich an dem eigentlichen Tool nicht viel geändert, aber es gibt mit PHP Monitor einen netten Helfer für die Statusbar und DBngin kann euch helfen verschiedene Datenbanksysteme/-versionen zu verwalten.

Außerdem habe ich einmal genauer erklärt, da ich selber wieder drüber gestolpert bin, wie man Composer in der PATH-Variable ergänzt und, dass es auch Ports für Windows und Linux gibt.

Was ist Valet?

Valet ist eine Entwicklungsumgebung für MacOS, die sehr schlank gehalten ist und sich über die Kommandozeile bedienen lässt. Von der Nutzung in der Kommandozeile sollte man sich nicht abschrecken lassen, ich bevorzuge auch eher ein GUI, aber nach der Installation müsst ihr euch eigentlich nur noch ein Befehl merken.

Info

Leider steht Laravel Valet offiziell nur für MacOS zur Verfügung. Allerdings gibt es auch Ports für Windows (Valet Windows) und Linux (Valet Linux). Diese Anleitung geht aber nur auf die MacOS-Version ein.

Valet läuft bei euch permanent im Hintergrund. Der große Vorteil gegenüber anderen Entwicklungsumgebung ist meiner Meinung nach die Leichtigkeit, die es gerade erlaubt dauerhaft im Hintergrund zu laufen. Zwar nutzen PHP, MySQL, NGINX Systemressourcen aber wirklich nur minimal (außer ihr ladet GB an Daten in die Datenbank). Außerdem müsst ihr Valet so nie starten, sondern wenn ihr eine konfigurierte Domain mit der Endung .test aufruft, ist die Website direkt da.

Installation

Benötigte Zeit: 5 Minuten

Die Installation von Laravel Valet ist sicherlich nicht die Einfachste aber hat man es einmal geschafft, ist es wirklich simpel. Versprochen!

  1. PHP installieren

    Zuerst müsst ihr PHP und MySQL auf eurem Mac installieren. Das geht am einfachsten mit Homebrew. Gebt die folgenden Befehle der Reihe nach ein;
    PHP installieren: brew install php
    Der benötigte Webserver, in diesem Fall NGINX, wird im 5. Schritt direkt mit Laravel Valet installiert.

  2. Datenbank installieren

    Für WordPress brauchen wir eine MySQL-Dankenbank. Diese können wir entweder auch mit Homebrew installieren:
    MySQL Datenbank: brew install mysql
    MySQL starten: brew services start mysql@8.0
    Oder alternativ, vor allem wenn ihr für andere Projekte noch Postgres, Redis oder unterschiedliche Datenbankversionen benötigt, ladet euch das kostenlose Programm DBngin herunter. Dort könnt ihr ganz schnell eine MySQL-Datenbank starten und wenn benötigt auch Postgres oder Redis.

  3. Composer installieren

    Um Valet zu installieren, benötigt ihr außerdem noch den Abhängigkeitsmanager Composer.

  4. PATH-Variable ergänzen

    Wenn ihr das erste Mal Composer nutzt, müsst ihr noch den .composer/vendor/bin Ordner zu der $PATH-Variable hinzufügen. Ansonsten könnt ihr den Schritt überspringen.
    Seit MacOS 10.15 Catalina (ab 2019) nutzt MacOS, ZSH als Standard-Shell und nicht mehr GNU Bash. Deswegen müsst ihr in der versteckten Datei .zshrc (und nicht mehr .bashrc, wie in vielen Anleitungen im Internet noch beschrieben) in eurem Benutzerordner folgendes ergänzen export PATH="$HOME/.composer/vendor/bin:$PATH"
    Am einfachsten geht das mit dem Befehl:
    echo 'export PATH="$HOME/.composer/vendor/bin:$PATH"' >> ~/.zshrc
    Anschließend müsst ihr noch die Änderungen neu laden:
    source ~/.zshrc
    Anschließend sollte der Befehl composer about funktionieren.

  5. Laravel Valet über Composer laden

    Anschließend könnt ihr endlich Valet selber installieren mit composer global require laravel/valet.

  6. Valet installieren

    Jetzt solltet ihr in Terminal den Befehl valet install ausführen können und Valet installiert und konfiguriert für euch noch NGINX als Webserver. Wenn nicht, ist in Schritt 4 etwas schiefgelaufen.

Nutzung

Nach der doch etwas aufwendigen Installation ist die weitere Nutzung total simpel. Ladet euch WordPress herunter, entpackt es in einen Ordner eurer Wahl und führt in diesem Ordner den Befehl valet link meine-domain aus. Anschließend könnt ihr die Website im Browser unter der Domain http://meine-domain.test aufrufen.

Was dann noch fehlt, ist die Datenbank. Diese könnt ihr über die Kommandozeile steuern oder ihr ladet euch eine GUI herunter z.B. Sequel Pro. Der Benutzername lautet root. Ein Passwort ist lokal nicht gesetzt, d.h. ihr könnt einfach das Feld leer lassen. Für eine lokale Entwicklungsumgebung sollte das kein Problem sein.

Erstellt in der Datenbank eine neue Tabelle z.B. wordpress und passt die Zugangsdaten in der wp-config.php an:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpress' );

/** MySQL database username */
define( 'DB_USER', 'root' );

/** MySQL database password */
define( 'DB_PASSWORD', '' );

Anschließend könnt ihr die berühmte 5-Minuten Installation abschließend und könnt lokal mit WordPress anstellen was ihr wollt.

Valet erkennt übrigens automatisch WordPress und funktioniert neben Laravel auch mit weiteren CMS und PHP Frameworks wie Drupal, Craft, Joomla… Es ist sogar möglich seinen eigenen Treiber zu schreiben.

Bonus

Eigentlich benötigt ihr nur den Befehl valet link aber es gibt doch noch einige interessante Funktionen von Valet die einen anderen Befehl verlangen:

  • valet park und alle Unterverzeichnisse im aktuellen Verzeichnis z.B. ~/Sites sind über den Verzeichnisnamen für die .test-Domain zugänglich z.B. ~/Sites/wordpress-1 ~/Sites/wordpress-2wordpress-1.test und wordpress-2.test
  • valet secure meine-domain und eure Domain ist über https erreichbar.
  • valet share in dem WordPress-Ordner und ihr könnt die Seite über Ngrok öffentlich im Internet teilen
  • valet forget vergisst das aktuelle Verzeichnis wieder
  • valet paths zeigt alle geparketen Verzeichnisse an

NGINX Konfiguration anpassen

Wenn ihr eure lokale Seite mithilfe von valet share mit einem SSL-Zertifikat ausgestattet habt, könnt ihr unter ~/.config/valet/Nginx/ die NGINX-Konfiguration finden und anpassen.

Dort könnt ihr z.B. fehlende Bilder von eurer echten Seite laden, wenn ihr diese lokal gecloned habt.

PHP updaten oder Version wechseln

Eine neue PHP Version müsst ihr über Homebrew updaten: brew upgrade php und anschließend Valet darüber informieren mit valet use php

Außerdem könnt ihr mit Homebrew ältere PHP-Versionen brew install php@7.3 installieren. Anschließend könnt ihr Valet befehlen diese Version zu verwenden: valet use php@7.3

Zurück auf die aktuellste installierte Version geht es mit valet use php

Mit PHP Monitor, Valet von der Statusbar aus steuern

Mit der kleinen App PHP Monitor könnt ihr Valet von der Statusbar aus steuern und so schnell zwischen installierten PHP Versionen wechseln oder einzelne Dienste (PHP, NGINX…) neu starten.

Installieren & updaten könnt ihr die App auch über Homebrew:

brew tap nicoverbruggen/homebrew-cask
brew install --cask phpmon

Meistens möchte man lokal ja ein eigenes Plugin oder Theme entwickeln. Das will man aber meistens nicht direkt unter wp-content erledigen. Ihr könnt aber mit einem symbolischen Link Abhilfe schaffen:

Für Plugins:

cd ~/pfad/zu/wordpress/wp-content/plugins
ln -s ~/pfad/zu-eurem-plugin/mein-plugin mein-plugin

Für Themes:

cd ~/pfad/zu/wordpress/wp-content/themes
ln -s ~/pfad/zu-eurem-theme/mein-theme mein-theme

Wenn etwas kaputt geht

Leider geht stellenweise auch mal etwas kaputt, z.B. wenn man versucht eine neue PHP-Version zu installieren. Mir hilft da oft einfach noch einmal valet install auszuführen. Hat bisher 90% meiner Probleme gelöst.

Fazit

Ich bin echt ein großer Fan von Laravel Valet und finde es deutlich praktischer als eine Entwicklungsumgebung auf Docker- oder Virtualbox-Basis. Kein Starten, kein Abschalten, um Arbeitsspeicher zu sparen und eine einfache Bedingung sind große Vorteile. Die Installation ist sicherlich etwas aufwendig, aber kein Hexenwerk.

Laravel Tools für WordPress

Dieser Beitrag ist Teil meiner kleinen Serie Laravel Tools für WordPress, wo ich euch Tools vorstelle, die ich aus der Laravel-Welt kenne, aber auch problemlos für WordPress genutzt werden können.

]]>
https://go-around.de/blog/laravel-valet-wordpress/feed/ 9
WordPress Snippet: Revisionen für Wiederverwendbare Blöcke aktivieren https://go-around.de/blog/wiederverwendbare-bloecke-revisionen/ https://go-around.de/blog/wiederverwendbare-bloecke-revisionen/#comments Tue, 06 Apr 2021 11:13:08 +0000 https://go-around.de/?p=676 In meinen Augen sind die wiederverwendbaren Blöcke im WordPress Block Editor a.k.a. Gutenberg Gold wert. Ich nutze sie täglich. Allerdings wurde mit WordPress 5.7 die UI im Editor grundlegend geändert und sie integrieren sich fast nahtlos in den restlichen Content. Das für aber leider regelmäßig dazu, dass ein wiederverwendbarer Block von einem Autor unwissentlich bearbeitet wird. Eigentlich sollte das dank der Revisionen in WordPress kein Problem sein, leider sind sie aber für den wp_block Post Type, der für die wiederverwendbaren Blöcke verwendet wird, nicht aktiviert.

Es gibt dazu bereits ein Issue auf Github aber bis das im WordPress Core ankommt, wird noch viel Wasser den Rhein hinunterfließen. Zum Glück ist es, wie so oft in WordPress, nicht schwer die Revisionen für einen Post Type zu aktivieren. Einfach die Funktion add_post_type_support mit dem Post Type wp_block und dem Feature revisions aufrufen und ab sofort speichert WordPress jede Änderung an einem wiederverwendbaren Block als Revision.

function reusable_block_revisions() {
	add_post_type_support( 'wp_block', 'revisions' );
}
add_action( 'init', 'reusable_block_revisions' );

Alle wiederverwendbaren Blöcke kann man, etwas versteckt, im Block Editor unter Ansicht anpassen (die drei vertikalen Punkte oben ganz rechts) und dann Alle wiederverwendbaren Blöcke verwalten einzeln im Block Editor bearbeiten und in der Seitenleiste auch die Revisionen wie bekannt ansehen und wiederherstellen.

Das Snippet könnt ihr einfach in eure functions.php eures (Child-)Theme werfen oder ihr ladet dieses kleine Plugin in euren wp-content/plugins Ordner hoch und aktiviert es anschließend unter Plugins.

]]>
https://go-around.de/blog/wiederverwendbare-bloecke-revisionen/feed/ 3
Laravel Tools für WordPress: Debuggen mit `dd` & `dump` statt `print_r` https://go-around.de/blog/dd-dump/ https://go-around.de/blog/dd-dump/#comments Wed, 27 Jan 2021 17:11:33 +0000 https://go-around.de/?p=581 Das Diagnostizieren von Fehler beim Programmieren von WordPress Plugins & Themes in PHP sieht bei mir meistens wie folgt aus:

// ...
echo '<code>';
print_r($meine_variable_in_der_ich_einen_fehler_vermute);
echo '</code>';
exit;
// oder
echo '<pre>';
var_dump($meine_variable_in_der_ich_einen_fehler_vermute);
echo '</pre>';
die;

Nicht besonders elegant, aber so sieht meistens die Praxis in PHP aus. Selbst in der offiziellen PHP Dokumentation gibt es keine sinnvollen Vorschläge, wie man in PHP sauber Fehler diagnostizieren kann.

Der richtige Weg: Xdebug

Sicherlich ist Xdebug das beste Werkzeug um Fehler im PHP Code zu suchen. Es hält die Ausführung von PHP an und man kann sich alle aktuell initialisierten Variablen genau anschauen.

Allerdings stehe ich mit Xdebug absolut auf Kriegsfuß. Die Installation ist leider alles andere als einfach. Ich brauche meistens 1-2 Stunden um Xdebug auf meinen Mac zum Laufen zu bekommen. Dann bin ich aber meistens so genervt, dass ich Feierabend mache und Xdebug einige Tage in Ruhe lasse. Brauche ich es dann ein paar Tage später wieder, ist schon wieder irgendetwas kaputt, z.B. Xdebug hält die Ausführung nicht an, obwohl ich einen Breakpoint gesetzt habe. In anderen Dateien funktioniert es aber ohne Probleme ?.

Statt wieder 1-2 Stunden in das Debuggen des Debuggers zu investieren, spring ich dann wieder auf die alt bewährte Methode print_r…, die immer funktioniert.

dd & dump

Aus der Laravel-Welt (wobei diese auf einem Synfony Component basieren) sind mir die zwei kleine Hilfsfunktionen dd & dump bekannt, die im Prinzip das gleich wie print_r bzw. var_dump machen, aber viel kürzer zu schreiben sind und die Ausgabe hübsch machen.

dump des WP_Query Objektes

dump gibt einfach eine oder mehrere Variable aus:

dump($value);

dump($value1, $value2, $value3, ...);

dd ist eine Abkürzung für dump & die und gibt eine oder mehrere Variablen aus und beendet anschließend die Ausführung:

dd($value);

dd($value1, $value2, $value3, ...);

In WordPress nutzen

Kann man das nicht auch in WordPress nutzen? Natürlich und es gibt sogar schon ein passendes Plugin: Laravel DD for WordPress

Einfach in der Entwicklungsumgebung installieren & aktivieren und fröhlich dd & dump schreiben!

Nicht vergessen solltet ihr aber alle dd & dump’s vor dem Push in die Live-Seite wieder zu entfernen (ist mir auch schon passiert). Sonst gibt es sicherlich wieder ein paar nette Fehler zu debuggen.

Next Level: Ray

Noch ein Schritt weiter geht die kostenpflichtige App Ray (29€/Jahr, kann aber kostenlos getestet werden) für MacOS. Statt dump($value) schreibt man ray($value) und die Ausgabe erfolgt direkt schön aufbereitet in der Ray App statt im Browser.

Um Ray in WordPress nutzen zu können, müsst ihr neben der Ray App in eurer Entwicklungsumgebung das Ray WordPress Plugin installieren. Anschließend kann das debuggen beginnen.

Einen guten Eindruck vermittelt das folgende kurze Video:

Durch Laden des Videos akzeptierst du die Datenschutzerklärung von Vimeo. Video laden Auswahl speichern & immer Vimeo laden

Ray wurde von Spatie, einer belgischen Agentur spezialisiert auf Laravel, entwickelt. Spatie ist in der Laravel Community dafür bekannt sehr viele Open Source Laravel Packages zu pflegen. Zunehmend entstehen aber auch größere jedoch kostenpflichtige Produkte wie Ray oder Mailcoach (Newsletter-Versand). Sowohl die Packages als auch die Produkte haben eine außergewöhnlich hohe Codequalität und werden bei neuen Laravel-Releases innerhalb weniger Tagen geupdated. Alleine deswegen kann man hier die 29€ pro Jahr (kein Abo nur eine jährliche Lizenz) getrost investieren.

Laravel Tools für WordPress

Dieser Beitrag ist Teil meiner kleinen Serie Laravel Tools für WordPress, wo ich euch Tools vorstelle, die ich aus der Laravel-Welt kenne, aber auch problemlos für WordPress genutzt werden können.

]]>
https://go-around.de/blog/dd-dump/feed/ 3
Laravel Tools für WordPress: Webpack in elegant mit Laravel Mix 6 https://go-around.de/blog/laravel-mix/ https://go-around.de/blog/laravel-mix/#comments Wed, 20 Jan 2021 07:11:39 +0000 https://go-around.de/?p=277 In der kleinen Serie zu Laravel Tools für WordPress, habe ich euch bereits Laravel Valet für die lokale Entwicklungsumgebung vorgestellt. Heute geht es wieder um ein Tool, was euch bei der Entwicklung von Themes & Plugins helfen kann. Besonders, wenn ihr an Block Editor (Gutenberg) Blöcken schraubt.

Laravel Mix vereinfacht euch die Arbeit mit Webpack enorm und spätestens, wenn ihr euren ersten Block in JavaScript programmiert, kommt ihr nicht mehr an Webpack (oder einem anderen JavaScript-Modul-Packer) vorbei. Die Konfiguration von Webpack empfinde ich aber als sehr kompliziert. Vor allem, wenn man noch nie mit React gearbeitet hat. Laravel Mix nimmt euch die Konfiguration in 80% der Fälle ab und reduziert den Konfigurationsaufwand extrem.

Update

Mit Laravel Mix 6 gab es einige Breaking Changes an der API. Ich habe den Artikel entsprechend geupdated.

Laravel Mix 6 setzt PostCSS 8 voraus. Wenn ihr von einer früheren Version upgraded, stellt erst sicher, dass alle Packages mit PostCSS 8 kompatibel sind.

Beispiel: Die webpack.config.js vom Gutenberg Plugin umfasst 157 Zeilen. Mit Laravel Mix reichen euch die folgenden zwei Zeilen in der webpack.mix.js:

let mix = require('laravel-mix');
mix.js('blocks/myblock.js', 'dist/').react();

Installation

Laravel Mix könnt ihr genau wie Webpack und alle anderen Module/Abhängigkeiten über NPM installieren. Solltet ihr NPM noch nicht in eurem Plugin/Theme initialisiert haben, müsst ihr das zuerst erledigen.

Wechselt dazu im Terminal/Konsole in euer Plugin/Theme Verzeichnis und führt npm init -y aus. Anschließend habt ihr eine package.json Datei in eurem Verzeichnis.

Als nächstes installiert ihr Laravel Mix als Abhängigkeit: npm install laravel-mix --save-dev

Anschließend müsst ihr im Root-Verzeichnis die Laravel Mix-Konfigurationsdatei anlegen. Erstellt einfach eine leere Datei mit dem Namen webpack.mix.js z.B. mit dem Befehl:

touch webpack.mix.js

Inhaltlich ist nur wichtig, dass ihr laravel-mix required und das Objekt mix für die weitere Konfiguration zur Verfügung steht.

// webpack.mix.js

let mix = require('laravel-mix');

mix.js('src/app.js', 'dist').sass('src/app.scss', 'dist/');

Das Beispiel mix.js('src/app.js', 'dist/').sass('src/app.scss', 'dist/'); kompiliert die app.js Datei im Ordner src und gibt sie im Ordner dist als app.js wieder aus und macht das gleiche mit der SASS-Datei app.scss, die als Stylesheet app.css ausgegeben wird.

Um euch lange webpack-Befehle in der Konsole zu sparen, solltet ihr in eurer package.json noch folgende scripts ergänzen:

"scripts": {
    "development": "mix",
    "watch": "mix watch",
    "watch-poll": "mix watch -- --watch-options-poll=1000",
    "hot": "mix watch --hot",
    "production": "mix --production",
    "prod": "npm run production"
}

Anschließend könnt ihr einfach npm run watch starten und Webpack kompiliert euer JavaScript/CSS sofort neu, wenn ihr beim Entwickeln etwas an einer Datei ändert und speichert. Zum Schluss kompiliert euch Webpack mit npm run prod eurer fertiges JavaScript/CSS, was ihr an eure Nutzer ausliefern könnt.

Block kompilieren

Entscheidend ist immer, was ihr als Funktion verwendet. Da Gutenberg auf React basiert, können wir unseren Block mit der mix.react Funktion kompilieren:

let mix = require('laravel-mix');
mix.js('blocks/myblock.js', 'dist/').react();
Info

Falls ihr anschließend eine Fehlermeldung erhaltet, installiert noch React über npm:

npm install react --save

Zwar benötigt ihr nicht zwingend für die Entwicklung eines (einfachen) Blocks Webpack bzw. React, es macht aber einfach viel mehr Spaß mit import zu arbeiten und dank JSX statt …

return wp.element.createElement('p', { class: 'welcome' }, 'Hallo World')

… einfach …

return <p className="welcome">Hallo World</p>

… zu schreiben.

Übrigens installiert Laravel Mix die benötigten Abhängigkeiten wirklich erst, wenn man eine entsprechende Funktion z.B. mix.react verwendet. So wird der node_modules Ordner nicht unnötig aufgebläht.

Abhängigkeiten für euren Block könnt ihr entweder aus dem window.wp Objekt beziehen:

const { RichText } = wp.blockEditor;

Oder installiert die einzelnen Module via npm z.B. npm install @wordpress/block-editor --save und importiert sie in eurer JavaScript-Datei:

import { RichText } from '@wordpress/block-editor'

CSS Preprocessor verwenden

Larvel Mix hilft euch auch mit eurem CSS z.B., wenn ihr einen CSS-Transformator wie PostCSS, Sass oder LESS verwenden wollt.

Auch hier reicht (jeweils) nur eine Zeile:

mix.sass(src, output);
mix.less(src, output);
mix.postCss(src, output, [require('postcss-some-plugin')()]);

Und vieles mehr…

Laravel Mix kann euch noch bei vielen weiteren sonst nervigen Webpack-Konfigurationen helfen, zum Beispiel:

  • BrowserSync: Jedes Mal, wenn ihr eine Änderung an einer Datei vornehmt und speichert, lädt bzw. synchronisiert BrowserSync eure Testumgebung in eurem Browser.
  • Versioning: Jedes Mal, wenn ihr sich euer Output ändert, speichert Laravel Mix den Datei-Hash in der mix-manifest.json. Mit einer Hilfsfunktion, könnt ihr die mix-manifest.json in eurem WordPress Theme/Plugin auslesen und als Version für wp_register_style bzw. wp_register_script verwenden.
  • Minifizieren & Kombinieren: Ihr könnt Laravel Mix bzw. Webpack auch einfach einzelne CSS/JS-Datein kombinieren oder minifizieren lassen.

Mehr Details findet ihr in der Dokumentation zu Laravel Mix.

Fazit

Ich finde die Lernkurve bei Webpack einfach viel zu steil und bin sehr froh, dass man mit Laravel Mix alle wichtigen Features mit ein paar Zeilen verständlichen Codes lösen kann. Sicherlich holt man sich so eine zusätzliche Abhängigkeit ins Projekt, aber durch die Einfachheit von Laravel Mix sehe ich da auch in der Zukunft keine großen Probleme. Zur Not kann man sehr einfach über mix.dump() auf eine eigene Webpack-Konfiguration umsteigen.

Alternativen

Speziell für Blöcke gibt es das Toolkit create-guten-block von Ahmad Awais. Es konfiguriert ebenfalls Webpack perfekt für diesen Einsatz.

Eure Erfahrung?

Konfiguriert ihr Webpack selber? Nutzt ihr ein anderes Build Tool? Habt ihr bereits Laravel Mix ausprobiert? Hinterlasst gerne ein Kommentar!

Laravel Tools für WordPress

Dieser Beitrag ist Teil meiner kleinen Serie Laravel Tools für WordPress, wo ich euch Tools vorstelle, die ich aus der Laravel-Welt kenne, aber auch problemlos für WordPress genutzt werden können.

]]>
https://go-around.de/blog/laravel-mix/feed/ 3
Vue.js Components im WordPress Block Editor / Gutenberg anzeigen https://go-around.de/blog/vuejs-components-wordpress-block-editor/ https://go-around.de/blog/vuejs-components-wordpress-block-editor/#comments Thu, 07 Jan 2021 17:38:27 +0000 https://go-around.de/?p=565 Gutenberg basiert ja (leider) auf React. Ich programmiere aber schon seit Jahren viel lieber mit Vue.js 2. Zwar habe ich mich damit abgefunden Blöcke für den Block Editor aka Gutenberg in React zu schreiben (wobei man nur sehr begrenzt eigentlich React verwendet, eher noch JSX), aber trotzdem verwende ich für einige Blöcke Vue.js. Im Fronend kein Problem, aber eine Vorschau im Block Editor angezeigt zu bekommen, inkl. Änderungen an den Attributen, war eine echte Herausforderung.

I.d.R. wird Vue.js 2 für die Komponenten einmal beim Laden der Seite initialisiert:

new Vue({
  el: document.querySelector('.vue'),
})

Wird aber, wie im Block Editor üblich, das HTML ständig ausgetauscht, muss auch ständig Vue neu initialisiert werden. Mein Problem: Ich weiß nicht genau wann! Jedes Mal, wenn die edit-Funktion des Blocks ausgeführt wird bedeutet dies massive Performanceprobleme.

Längere Zeit hatte ich deswegen Vuera im Einsatz um Vue in React zu nutzen. So richtig rund lief das aber bei mir nie. Vor allem nicht, wenn der Block serverseitig mit ServerSideRender im Editor gerendert wird. Hier gibt es keinen Hinweis, wann das Laden abgeschlossen worden ist und Vue neu initialisiert werden müsste.

Web Components to the rescue

Seit einigen Wochen habe ich Web Components für mich entdeckt. Dabei werden die Benutzerdefinierten Elemente = Custom Elements im window Interface registriert und immer, wenn der Browser ein definiertes Element erkennt, z.B. <vue-wrapper>, wird es initialisiert. Einmal registriert, muss ich mich also nicht darum kümmern, Vue.js 2 zum richtigen Zeitpunkt erneut zu initialisieren.

Ich erstelle mir also ein einfaches Custom Element, das als einzige Aufgabe hat, beim Verbinden über den connectedCallback mit dem DOM, Vue für dieses Element el über this zu initialisieren.

import Vue from 'vue';
import MyComponent from './my-component';

Vue.component('my-component', MyComponent); // Component global registrieren

class VueWrapper extends HTMLElement {
    connectedCallback() {
		new Vue({
		    el: this,
		});
	}
}
window.customElements.define('vue-wrapper', VueWrapper );

Im HTML muss ich dann nur noch meinen Vue Componen mit dem vue-wrapper umschließen:

<vue-wrapper>
    <my-component></my-component>
</vue-wrapper>

Immer wenn der Browser im DOM ein neues <vue-wrapper> Custom Element erkennt, wird er Vue für euch zuverlässig initialisieren.

Vue.js Component als Web Component

Ich bin sogar noch einen Schritt weiter gegangen und habe meinen Vue.js 2 Component als Web Component bzw. Custom Element umgesetzt. Dafür gibt es aktuell zwei NPM Packages:

  • @vue/web-component-wrapper: Die offizielle Implementation von Vue.js, welche allerdings schon seit zwei Jahren (Stand Januar 2021) keine Liebe mehr abgekommen hat. Probleme gibt es hier bei Objekten und Arrays als Props.
  • vue-custom-element: Meine Empfehlung aktuell, vor allem wenn man Objekte oder Arrays als Props übergeben möchte. Bekommt mehr Liebe ab.
Update

Mit Vue.js 3 kann man Vue.js-Components als Web Components direkt erstellen. Dafür müsst ihr die defineCustomElement Funktion importieren und den Rückgabewert könnt ihr ganz normal über die Browser-API über customElements.define registrieren.

Hier ein Beispiel aus der Dokumentation von Vue 3:

import { defineCustomElement } from 'vue'

const MyVueElement = defineCustomElement({
  // normal Vue component options here
  props: {},
  emits: {},
  template: `...`,

  // defineCustomElement only: CSS to be injected into shadow root
  styles: [`/* inlined css */`]
})

// Register the custom element.
// After registration, all `<my-vue-element>` tags
// on the page will be upgraded.
customElements.define('my-vue-element', MyVueElement)

// You can also programmatically instantiate the element:
// (can only be done after registration)
document.body.appendChild(
  new MyVueElement({
    // initial props (optional)
  })
)

Anschließend könnt ihr den Web Component einfach ganz normal im DOM nutzen:

<my-vue-element></my-vue-element>

Sein Vue Component registriert man dann wie folgt:

import Vue from 'vue';
import vueCustomElement from 'vue-custom-element'
import MyComponent from './my-component';

Vue.use(vueCustomElement);

Vue.customElement('my-component', MyComponent);

Jetzt benötigt man auch keinen Wrapper mehr, sondern kann das Custom Element direkt verwenden:

<my-component></my-component>

Objekte & Arrays als Props

Möchte man Daten an seinen Component übergeben, ist das bei String, Number und Boolean kein Problem:

<my-component :status="true" :count="1" :text="My Component"></my-component>

Nur Objekte und Parameter machen hier Probleme. Es wird empfohlen diese direkt über JavaScript zu übergeben:

document.querySelector('my-component').data = [
    ...
];

Schöner wäre aber wie bei Vue.js üblich:

<my-component :data="[ ... ]"></my-component>

Damit es so funktioniert, muss man das Array/Objekt als JSON-String übergeben und im connectedCallback in ein echtes Array oder Objekt umwandeln:

import Vue from 'vue';
import vueCustomElement from 'vue-custom-element'
import MyComponent from './my-component';

Vue.use(vueCustomElement);

Vue.customElement('my-component', MyComponent, {
    connectedCallback() {
        this.data = this.hasAttribute(':data') ? JSON.parse(this.getAttribute(':data')) : undefined;
    }
});
Achtung

Ich konnte als Attribute nicht den selber Namen wie für den Prop verwenden. Deswegen habe ich als Attribute :data gewählt, als Prop data ohne : Das kommt der Vue-Syntax sehr nah.

In JSX wird aber kein : akzeptiert, hier könnte man stattdessen das Attribut mit data prefixen, z.B.

this.mydata = this.hasAttribute('data-mydata') ? JSON.parse(this.getAttribute('data-mydata') : undefined;

Fazit

JavaScript über Custom Elements initialisieren funktioniert nicht nur für Vue.js, sondern grundsätzlich für viele JavaScript-Frameworks und andere Libraries überall wo man ein Element für die Initialisierung übergeben muss.

]]>
https://go-around.de/blog/vuejs-components-wordpress-block-editor/feed/ 4
Buchhaltung automatisieren: Meine Entscheidung https://go-around.de/blog/buchhaltung-automatisieren-entscheidung/ https://go-around.de/blog/buchhaltung-automatisieren-entscheidung/#comments Tue, 15 Dec 2020 15:39:54 +0000 https://go-around.de/?p=534 Meine kleine Serie zu meinem Versuch die Buchhaltung zu automatisieren, möchte ich heute mit einer Entscheidung zu Ende bringen. Eine Entscheidung, welches Tool ich in Zukunft verwenden werden.

Getestet habe ich Get My Invoice, welches ich über ein Jahr lang verwendet habe, sevDesk, Fastbill und Lexoffice. Meine Anforderungen habe ich bereits am Anfang klar definiert. 100% werden diese von keinem der Anbieter erfüllt, aber ich habe trotzdem einen Kompromiss gefunden.

Die bisherigen Artikel der Serien, die mit der Entscheidung (vorerst) zu Ende geht, findet ihr hier:

  1. Mein Weg zur automatisierten Buchhaltung
  2. Get My Invoices: Meine Erfahrungen nach über einem Jahr
  3. sevDesk: Meine persönlicher (erster) Eindruck
  4. Fastbill: Mein persönlicher (erster) Eindruck
  5. Lexoffice: Mein persönlicher (erster) Eindruck
  6. Meine Entscheidung

Die Entscheidung

Ich will auch nicht lange um den heißen Brei herumreden: Ich setzte jetzt bereits seit drei Monaten sevDesk ein und bin bisher auch immer noch zufrieden!

Gehen wir doch einfach einmal die Anforderungen durch und schauen, wo es noch Hakt:

  • Rechnungen schreiben, auf Englisch und inkl. CC per Email verschicken: Ich kann schnell und einfach Rechnungen schreiben und direkt per Email inkl. CC verschicken. Rechnungen auf Englisch sind kein Problem und mit den Vorlagen auch schnell erstellbar.
  • Belege per Email weiterleiten: Rechnungen, Gutschriften und Belege von Dritten kann ich einfach an autobox@sevdesk.email weiterleiten. Hier muss ich nur aufpassen, die in sevDesk hinterlegte Email-Adresse als Absender zu verwenden. Meine Rechnungs-Email-Adresse, die ich bei vielen Anbietern hinterlegt habe, funktioniert damit leider nicht mehr. Ich muss immer darauf achten die Emails mit Belegen mit der richtigen Absender-Email-Adresse weiterzuleiten. Etwas nervig. Schön wäre es, wenn man bei sevDesk mehrere Email-Adressen als Absender erlauben könnte.
  • Belege in Fremdwährungen: Ein Manko von SevDesk ist, dass leider keine Belege in Fremdwährungen unterstützt werden. Als Workaround schreibe ich den Beleg erst fest, wenn ich die genaue Summe in Euro kenne, z.B. vom Kontoauszug. Ist zwar nervig aber funktioniert.
  • Konto, Kreditkarten, PayPal: Meine Kontobewegungen kann ich alle in sevDesk einsehen und jeder Zahlung einen Beleg zuordnen. Nur die Kontobewegungen von American Express kann ich leider nicht abrufen aber importieren. Ich habe mir dafür ein kleines Node.js-Script gebastelt, was die CSV-Datei in das richtige Format bringt.
  • Lernende Texterkennung: Die Texterkennung der Belege ist gut, aber nicht perfekt. Immerhin habe ich bei sevDesk bisher das Gefühl, mit jedem Beleg wird es wirklich besser und ich muss nicht wie früher bei Get My Invoice jedes Mal dieselben Fehler korrigieren.
  • Monatlicher Export: Bevor ich die Belege an meinen Steuerberater weiterleite, exportiere ich alle Belege und lege sie lokal in einem Ordner als Backup ab. Funktioniert gut!
  • Export an meinen Steuerberater: Mein Steuerberater bekommt die Belege und Zahlungen bequem per DATEV-Export und ist damit bisher glücklich, wobei wir hier noch ein Problem bei Zuordnung der Kundennummern lösen müssen.
  • Schnelle Ladezeiten: Wunderbar. An diesem Punkt hat mir sevDesk wirklich überzeugt. Die Webapp fühlt sich wirklich wie ein natives Programm an.
  • Gute Benutzerfreundlichkeit: Auch hier gibt es keine großen Punkte, wo mich der Workflow von sevDesk wirklich stört. Ich habe nicht das Gefühl irgendwo Zeit zu verschwenden.

Wie geht es weiter?

Zwar hat sevDesk meine Buchhaltung beschleunigt, trotzdem ist sie noch lange nicht vollständig automatisiert. Pro Monat muss ich, bzw. meine Frau, weiterhin gut einen Arbeitstag in die Buchhaltung investieren.

Ein Problem ist immer noch der Export der Belege aus den einzelnen Affiliate Netzwerken, mit denen ich zusammenarbeite. Hier habe ich angefangen mit Node.js und Puppeteer (Headless Browser) ein automatisches Script zu schreiben. Allerdings muss ich schon nach drei Monaten der Nutzung feststellen, dass der Pflegeaufwand enorm ist. Auf einmal wird eine komplett neue UI eingeführt, heißt ich muss das Script neu schreiben oder ein Popup blockiert das Script und ich muss doch wieder Hand anlegen.

Ich habe schon darüber nachgedacht für den Export doch wieder Get My Invoice zu nutzen oder einen andern Anbieter in dem Segment auszuprobieren. Der Kern meiner Buchhaltung soll aber weiterhin sevDesk bleiben.

Ich halte Euch auf dem Laufenden!

Hier noch einmal alle Teile dieser Serie:

  1. Mein Weg zur automatisierten Buchhaltung
  2. Get My Invoices: Meine Erfahrungen nach über einem Jahr
  3. sevDesk: Meine persönlicher (erster) Eindruck
  4. Fastbill: Mein persönlicher (erster) Eindruck
  5. Lexoffice: Mein persönlicher (erster) Eindruck
  6. Meine Entscheidung

]]>
https://go-around.de/blog/buchhaltung-automatisieren-entscheidung/feed/ 7
WordPress 5.6: Standard für die Verlinkung von Bildern setzen https://go-around.de/blog/wordpress-image-default-link-type/ https://go-around.de/blog/wordpress-image-default-link-type/#comments Wed, 09 Dec 2020 16:54:44 +0000 https://go-around.de/?p=524 Mit WordPress 5.6 wird endlich wieder die Option image_default_link_type im Block Editor/Gutenberg berücksichtigt. Für ihr oder ein anderer Nutzer eurer Website einen neuen Bild- oder Gallerie Block ein, werden die Bilder dann standardmäßig auf die Mediendatei, Anhangsseite oder (bisher der Standard) gar nicht verlinkt.

Die image_default_link_type Option könnt ihr über die „geheime“ wp-admin/options.php Seite festlegen.

  1. Ruft dazu einfach die entsprechende Optionen-Seite eurer Website auf z.B. go-around.de/wp-admin/options.php
  2. Sucht nach dem Eintrag image_default_link_type z.B. mit STRG + F bzw. CMD + F
  3. Setzt diesen Eintrag auf den gewünschten Wert:
    • none = keine Verlinkung
    • file = Mediendatei
    • post = Anhangsseite
  4. Öffnet einen beliebigen Beitrag im Block Editor und fügt ein Bild oder eine Gallerie ein.

Warum freue ich mich darüber so sehr? Mein Lightbox Plugin setzt für baguetteBox.js voraus, dass die hochauflösende Bilddatei als Link hinterlegt ist. Bisher musste man bei jedem Bild und jeder Gallerie immer daran denken diesen Wert anzupassen damit die Lightbox funktioniert. Man kann die Standardeinstellungen zwar ändern, die Option ist aber deutlich einfacher.

Danke an mkaz & ajlende die, die Option in Gutenberg zurückgebracht haben! Hier der Pull Request für den Image Block und Gallery Block.

]]>
https://go-around.de/blog/wordpress-image-default-link-type/feed/ 8
Tipp: Bildoptimierung-Plugin ShortPixel lebenslanges Abo für einmalig 49$ https://go-around.de/blog/shortpixel-lifetime/ https://go-around.de/blog/shortpixel-lifetime/#comments Sun, 15 Nov 2020 13:30:31 +0000 https://go-around.de/?p=521 Seit über drei Jahren nutze ich für die Optimierung der Bilder in WordPress ShortPixel. Die optimierten Bilder werden zwar lokal gespeichert, die eigentliche Optimierung erfolgt aber im Hintergrund auf den Servern von ShortPixel.

100 Credits (1 Credit = 1 Bild aber jedes optimierte Thumbnail zählt als ein Bild) sind pro Monat kostenlos. Das reicht leider bei weitem nicht und so habe ich in der Vergangenheit immer One Time Credits für ShortPixel gekauft z.B. 50.000 Credits für 30$. Für mich bisher eine faire Variante. Die Abos z.B. 12.000 Credits für 10$ haben mich bisher nicht gereizt bzw. mit hat das Preis-/Leistungsverhältnis nicht gefallen.

Update

Leider ist das Lifetime-Angebot ausgelaufen. Kommt aber bestimmt irgendwann wieder. Shortpixel kann ich weiterhin als Plugin empfehlen.

Durch Zufall (ich habe etwas zu Shortpixel gegoogled) bin ich auf das Angebot bei Appsumo gestoßen: Lebenslange 15.000 Credits pro Monat für einmalig 49$. Außerdem gibt es noch 125 GB CDN-Traffic pro Monat on top.

Info

Seid ihr noch kein Mitglied bei Appsumo, könnt ihr über die Freundschaftswerbung weitere 10$ Rabatt erhalten = 39$. Der Werber erhält ebenfalls 10$ Rabatt auf den nächsten Kauf.

Falls ihr noch kein Konto von ShortPixel habt, könnt ihr auch gerne dort meinen Einladungslink nutzen und 100 + 100 = 200 kostenlose Credits pro Monat erhalten. Ich erhalte so ebenfalls 100 Credits monatlich + 100 One Time Credits.

Reichen euch 15.000 Credits pro Monat nicht, könnt ihr auch bis zu 5 Lizenzen kaufen = 5 x 49$ = 245$ für 75.000 Credits und 625 GB CDN Traffic pro Monat.

Falls euch am Anfang die 15.000 Credits nicht ausreichen, um eure komplette WordPress-Mediathek zu optimieren, empfehle ich euch aber eher einmalig One Time Credits direkt bei ShortPixel zu kaufen z.B. 50.000 für 30$. Danach sollten 15.000 Credits pro Monat den meisten völlig ausreichen.

Was mit an Shortpixel besonders gefällt (im Vergleich zu anderen Bildoptmierungs-Plugins):

  • Optimierung erfolgt nach dem Upload im Hintergrund d.h. die Optimierung blockiert den Upload der Bilder nicht (damit hatte ich mal bei Optimus Probleme)
  • Gute Übersicht über die optimierten Bilder in der WordPress Mediathek
  • Backup wird angelegt bevor die Bilder optimiert werden
  • Bilder weniger aggressiv erneut komprimieren z.B. wenn die Optimierung zu deutlich sichtbar ist
  • One Time Credits die unbegrenzt gültig sind und nicht verfallen
  • Kostenlose WebP-Version der optimierten Bilder
  • Eigenes Regenerate Thumbnails Advanced Plugin, wodurch nur ausgewählte Thumbnails regeneriert & optimiert werden
  • Diverse Tools & APIs, die man auch über WordPress hinaus nutzen kann

Wie optimiert ihr eure Bilder in WordPress? Hinterlasst gerne ein Kommentar!

Falls ihr ein Plugin sucht, welches komplett kostenfrei ist und auf dem eigenen Server die Optimierung durchführt, schaut euch den Klassiker EWWW Image Optimizer an.

]]>
https://go-around.de/blog/shortpixel-lifetime/feed/ 3