Last active
January 25, 2026 12:35
-
-
Save nextab/375b76fd7f8dbe808bea3ae5a8759713 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| ############################################# | |
| # WordPress Standard-Installation Script | |
| # Für all-inkl Hosting mit WP CLI | |
| # Version: 3.1 - Multiple Fonts & Colors | |
| ############################################# | |
| # Farbcodes für Ausgabe | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' # No Color | |
| # Fehlerbehandlung | |
| set -e | |
| trap 'echo -e "${RED}Fehler in Zeile $LINENO${NC}"' ERR | |
| # Logging-Funktion | |
| log() { | |
| echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" | |
| } | |
| warning() { | |
| echo -e "${YELLOW}[WARNUNG]${NC} $1" | |
| } | |
| error() { | |
| echo -e "${RED}[FEHLER]${NC} $1" | |
| exit 1 | |
| } | |
| prompt() { | |
| echo -e "${BLUE}[EINGABE]${NC} $1" | |
| } | |
| ############################################# | |
| # INTERAKTIVE KONFIGURATION | |
| ############################################# | |
| echo "" | |
| echo "==========================================" | |
| echo " WordPress Installation Script" | |
| echo " Interaktive Konfiguration" | |
| echo "==========================================" | |
| echo "" | |
| # Datenbank-Einstellungen | |
| prompt "=== DATENBANK-EINSTELLUNGEN ===" | |
| read -p "Datenbank Name: " DB_NAME | |
| read -p "Datenbank Benutzer: " DB_USER | |
| read -sp "Datenbank Passwort: " DB_PASSWORD | |
| echo "" | |
| read -p "Datenbank Host [localhost]: " DB_HOST | |
| DB_HOST=${DB_HOST:-localhost} | |
| read -p "Tabellen-Präfix [wp_]: " DB_PREFIX | |
| DB_PREFIX=${DB_PREFIX:-wp_} | |
| echo "" | |
| prompt "=== WORDPRESS-EINSTELLUNGEN ===" | |
| read -p "Website URL (z.B. https://example.com): " WP_URL | |
| read -p "Website Titel: " WP_TITLE | |
| read -p "Admin Benutzername [nexTab]: " WP_ADMIN_USER | |
| WP_ADMIN_USER=${WP_ADMIN_USER:-nexTab} | |
| read -sp "Admin Passwort: " WP_ADMIN_PASSWORD | |
| echo "" | |
| read -p "Admin E-Mail [[email protected]]: " WP_ADMIN_EMAIL | |
| WP_ADMIN_EMAIL=${WP_ADMIN_EMAIL:[email protected]} | |
| echo "" | |
| prompt "=== THEME-EINSTELLUNGEN ===" | |
| read -p "GitHub Repository URL [https://github.com/nextab/nxt-block-theme.git]: " THEME_GITHUB_REPO | |
| THEME_GITHUB_REPO=${THEME_GITHUB_REPO:-https://github.com/nextab/nxt-block-theme.git} | |
| read -p "GitHub Branch [main]: " THEME_BRANCH | |
| THEME_BRANCH=${THEME_BRANCH:-main} | |
| read -p "Theme Name (z.B. Steinfels): " NEW_THEME_NAME | |
| NEW_THEME_SLUG=$(echo "$NEW_THEME_NAME" | tr '[:upper:]' '[:lower:]') | |
| read -p "Original Textdomain im Template [nxt-block-theme]: " OLD_TEXTDOMAIN | |
| OLD_TEXTDOMAIN=${OLD_TEXTDOMAIN:-nxt-block-theme} | |
| echo "" | |
| echo "==========================================" | |
| echo " ZUSAMMENFASSUNG" | |
| echo "==========================================" | |
| echo "Datenbank: $DB_NAME@$DB_HOST" | |
| echo "WordPress URL: $WP_URL" | |
| echo "Website Titel: $WP_TITLE" | |
| echo "Admin User: $WP_ADMIN_USER" | |
| echo "Theme: $NEW_THEME_NAME (Slug: $NEW_THEME_SLUG)" | |
| echo "==========================================" | |
| echo "" | |
| read -p "Alles korrekt? Installation starten? (j/n) " -n 1 -r | |
| echo "" | |
| if [[ ! $REPLY =~ ^[Jj]$ ]]; then | |
| error "Installation abgebrochen." | |
| fi | |
| echo "" | |
| ############################################# | |
| # 1. WORDPRESS CORE HERUNTERLADEN | |
| ############################################# | |
| log "Starte WordPress Installation..." | |
| # Prüfen ob bereits WordPress-Dateien vorhanden sind | |
| if [ -f "wp-config.php" ]; then | |
| warning "wp-config.php existiert bereits!" | |
| read -p "Möchtest du fortfahren und überschreiben? (j/n) " -n 1 -r | |
| echo | |
| if [[ ! $REPLY =~ ^[Jj]$ ]]; then | |
| error "Installation abgebrochen." | |
| fi | |
| fi | |
| # WordPress Core herunterladen (Deutsch) | |
| log "Lade WordPress Core herunter (Deutsch)..." | |
| wp core download --locale=de_DE --force | |
| log "WordPress Core erfolgreich heruntergeladen!" | |
| ############################################# | |
| # 2. WP-CONFIG.PHP ERSTELLEN | |
| ############################################# | |
| log "Erstelle wp-config.php..." | |
| wp config create \ | |
| --dbname="$DB_NAME" \ | |
| --dbuser="$DB_USER" \ | |
| --dbpass="$DB_PASSWORD" \ | |
| --dbhost="$DB_HOST" \ | |
| --dbprefix="$DB_PREFIX" \ | |
| --locale=de_DE \ | |
| --force | |
| log "wp-config.php erfolgreich erstellt!" | |
| ############################################# | |
| # 3. DATENBANK-VERBINDUNG PRÜFEN | |
| ############################################# | |
| log "Prüfe Datenbank-Verbindung..." | |
| if wp db check; then | |
| log "Datenbank-Verbindung erfolgreich!" | |
| else | |
| error "Datenbank-Verbindung fehlgeschlagen! Bitte Zugangsdaten prüfen." | |
| fi | |
| ############################################# | |
| # 4. WORDPRESS INSTALLIEREN | |
| ############################################# | |
| log "Installiere WordPress..." | |
| wp core install \ | |
| --url="$WP_URL" \ | |
| --title="$WP_TITLE" \ | |
| --admin_user="$WP_ADMIN_USER" \ | |
| --admin_password="$WP_ADMIN_PASSWORD" \ | |
| --admin_email="$WP_ADMIN_EMAIL" \ | |
| --skip-email | |
| log "WordPress erfolgreich installiert!" | |
| ############################################# | |
| # 5. EIGENES THEME VON GITHUB INSTALLIEREN | |
| ############################################# | |
| log "Installiere eigenes Theme: $NEW_THEME_NAME..." | |
| # Prüfen ob git verfügbar ist | |
| if ! command -v git &> /dev/null; then | |
| error "Git ist nicht installiert! Bitte Git installieren oder Theme manuell hochladen." | |
| fi | |
| # Temporäres Verzeichnis für den Clone | |
| TEMP_THEME_DIR="/tmp/nxt-theme-temp-$$" | |
| # Prüfen ob Ziel-Theme bereits existiert | |
| if [ -d "wp-content/themes/$NEW_THEME_NAME" ]; then | |
| warning "Theme '$NEW_THEME_NAME' existiert bereits!" | |
| rm -rf "wp-content/themes/$NEW_THEME_NAME" | |
| log "Altes Theme entfernt" | |
| fi | |
| # Theme von GitHub klonen | |
| log "Klone Theme von GitHub: $THEME_GITHUB_REPO..." | |
| if git clone --branch "$THEME_BRANCH" --single-branch --depth 1 "$THEME_GITHUB_REPO" "$TEMP_THEME_DIR"; then | |
| log "Theme erfolgreich von GitHub geklont!" | |
| else | |
| error "Fehler beim Klonen des Themes von GitHub!" | |
| fi | |
| # .git Ordner entfernen (nicht benötigt) | |
| rm -rf "$TEMP_THEME_DIR/.git" | |
| # Theme ins WordPress themes-Verzeichnis verschieben | |
| log "Verschiebe Theme nach wp-content/themes/$NEW_THEME_NAME..." | |
| mv "$TEMP_THEME_DIR" "wp-content/themes/$NEW_THEME_NAME" | |
| if [ ! -d "wp-content/themes/$NEW_THEME_NAME" ]; then | |
| error "Theme-Verschieben fehlgeschlagen!" | |
| fi | |
| log "Theme erfolgreich installiert!" | |
| # Textdomain ersetzen | |
| log "Ersetze Textdomain von '$OLD_TEXTDOMAIN' zu '$NEW_THEME_SLUG'..." | |
| cd "wp-content/themes/$NEW_THEME_NAME" || error "Konnte nicht ins Theme-Verzeichnis wechseln" | |
| # Liste der Dateien, die bearbeitet werden sollen | |
| FILES_TO_UPDATE=("style.scss" "style.css" "functions.php" "theme.json") | |
| # Zusätzlich alle PHP-Dateien im inc/ Verzeichnis hinzufügen | |
| if [ -d "inc" ]; then | |
| # Erstelle temporäre Dateiliste | |
| TEMP_FILE_LIST=$(mktemp) | |
| find inc -type f -name "*.php" > "$TEMP_FILE_LIST" | |
| while IFS= read -r file; do | |
| FILES_TO_UPDATE+=("$file") | |
| done < "$TEMP_FILE_LIST" | |
| rm -f "$TEMP_FILE_LIST" | |
| fi | |
| # Textdomain in allen Dateien ersetzen | |
| for file in "${FILES_TO_UPDATE[@]}"; do | |
| if [ -f "$file" ]; then | |
| sed -i "s/Text Domain: $OLD_TEXTDOMAIN/Text Domain: $NEW_THEME_SLUG/g" "$file" | |
| sed -i "s/'$OLD_TEXTDOMAIN'/'$NEW_THEME_SLUG'/g" "$file" | |
| sed -i "s/\"$OLD_TEXTDOMAIN\"/\"$NEW_THEME_SLUG\"/g" "$file" | |
| log "Textdomain in $file ersetzt" | |
| fi | |
| done | |
| # Theme Name und Theme URI in style.scss und style.css aktualisieren | |
| if [ -f "style.scss" ]; then | |
| sed -i "s/Theme Name: nexTab Block Theme Template/Theme Name: $NEW_THEME_NAME/g" "style.scss" | |
| sed -i "s|Theme URI: https://nextab.de|Theme URI: $WP_URL|g" "style.scss" | |
| log "Theme Name und URI in style.scss aktualisiert" | |
| fi | |
| if [ -f "style.css" ]; then | |
| sed -i "s/Theme Name: nexTab Block Theme Template/Theme Name: $NEW_THEME_NAME/g" "style.css" | |
| sed -i "s|Theme URI: https://nextab.de|Theme URI: $WP_URL|g" "style.css" | |
| log "Theme Name und URI in style.css aktualisiert" | |
| fi | |
| cd - > /dev/null || error "Konnte nicht zurück ins Root-Verzeichnis wechseln" | |
| log "Textdomain erfolgreich ersetzt!" | |
| # PHP-Version prüfen | |
| log "Prüfe PHP-Version..." | |
| PHP_VERSION=$(php -r "echo PHP_VERSION;" 2>/dev/null || echo "unknown") | |
| PHP_MAJOR_MINOR=$(echo "$PHP_VERSION" | cut -d "." -f 1,2) | |
| log "Erkannte PHP-Version: $PHP_VERSION (Major.Minor: $PHP_MAJOR_MINOR)" | |
| # Theme-Anforderungen prüfen und ggf. anpassen | |
| THEME_STYLE_CSS="wp-content/themes/$NEW_THEME_NAME/style.css" | |
| THEME_STYLE_SCSS="wp-content/themes/$NEW_THEME_NAME/style.scss" | |
| THEME_PHP_REQUIREMENT=$(grep "Requires PHP:" "$THEME_STYLE_CSS" | head -n 1 | sed 's/.*Requires PHP: *//' | xargs) | |
| log "Theme benötigt PHP: $THEME_PHP_REQUIREMENT" | |
| # Wenn PHP-Version bekannt ist, aber niedriger als Anforderung | |
| if [ "$PHP_VERSION" != "unknown" ]; then | |
| # Version_compare simulieren mit sort -V | |
| if [ "$(printf '%s\n' "$THEME_PHP_REQUIREMENT" "$PHP_MAJOR_MINOR" | sort -V | head -n1)" != "$THEME_PHP_REQUIREMENT" ]; then | |
| warning "PHP-Version $PHP_VERSION ist niedriger als erforderlich ($THEME_PHP_REQUIREMENT)" | |
| warning "Passe Theme-Anforderung automatisch auf PHP $PHP_MAJOR_MINOR an..." | |
| # Passe beide Dateien an | |
| sed -i "s/Requires PHP: $THEME_PHP_REQUIREMENT/Requires PHP: $PHP_MAJOR_MINOR/g" "$THEME_STYLE_CSS" | |
| sed -i "s/Requires PHP: $THEME_PHP_REQUIREMENT/Requires PHP: $PHP_MAJOR_MINOR/g" "$THEME_STYLE_SCSS" | |
| log "Theme-Anforderung erfolgreich angepasst auf PHP $PHP_MAJOR_MINOR" | |
| else | |
| log "PHP-Version $PHP_VERSION erfüllt Theme-Anforderung ($THEME_PHP_REQUIREMENT) ✓" | |
| fi | |
| fi | |
| # Theme aktivieren mit WP CLI | |
| log "Aktiviere Theme '$NEW_THEME_NAME'..." | |
| wp theme activate "$NEW_THEME_NAME" | |
| log "Theme erfolgreich aktiviert!" | |
| ############################################# | |
| # 6. STANDARD-PLUGINS INSTALLIEREN | |
| ############################################# | |
| log "Installiere Standard-Plugins..." | |
| # Liste der zu installierenden Plugins | |
| PLUGINS=( | |
| "atarim-visual-collaboration" | |
| "create-block-theme" | |
| "duplicate-post" | |
| "fluent-smtp" | |
| "gdpr-compliant-recaptcha-for-all-forms" | |
| "seo-by-rank-math" | |
| ) | |
| # Plugins installieren und aktivieren | |
| for plugin in "${PLUGINS[@]}"; do | |
| log "Installiere Plugin: $plugin..." | |
| if wp plugin install "$plugin"; then | |
| log "Plugin '$plugin' erfolgreich installiert" | |
| else | |
| warning "Plugin '$plugin' konnte nicht installiert werden" | |
| fi | |
| done | |
| log "Standard-Plugins erfolgreich installiert!" | |
| ############################################# | |
| # 7. STANDARD-PLUGINS ENTFERNEN | |
| ############################################# | |
| log "Entferne Standard-Plugins..." | |
| # Akismet deinstallieren | |
| if wp plugin is-installed akismet; then | |
| wp plugin uninstall akismet --deactivate | |
| log "Akismet entfernt" | |
| else | |
| warning "Akismet nicht gefunden" | |
| fi | |
| # Hello Dolly deinstallieren | |
| if wp plugin is-installed hello; then | |
| wp plugin uninstall hello --deactivate | |
| log "Hello Dolly entfernt" | |
| else | |
| warning "Hello Dolly nicht gefunden" | |
| fi | |
| log "Standard-Plugins erfolgreich entfernt!" | |
| ############################################# | |
| # 8. DEFAULT CONTENT AUFRÄUMEN | |
| ############################################# | |
| log "Räume Default-Content auf..." | |
| # "Hallo Welt!" Post (ID 1) löschen | |
| if wp post exists 1; then | |
| wp post delete 1 --force | |
| log "Default-Post 'Hallo Welt!' gelöscht (ID 1)" | |
| else | |
| warning "Default-Post nicht gefunden (ID 1)" | |
| fi | |
| # Alle Kommentare löschen (meist nur zu ID 1) | |
| ALL_COMMENTS=$(wp comment list --format=ids 2>/dev/null || echo "") | |
| if [ -n "$ALL_COMMENTS" ]; then | |
| for comment_id in $ALL_COMMENTS; do | |
| wp comment delete "$comment_id" --force | |
| done | |
| log "Alle Kommentare gelöscht" | |
| else | |
| log "Keine Kommentare vorhanden" | |
| fi | |
| # Alle Default-Pages löschen (ID 2, 3, etc.) | |
| # WordPress erstellt standardmäßig: Sample Page (ID 2) und Privacy Policy (ID 3) | |
| ALL_PAGES=$(wp post list --post_type=page --format=ids 2>/dev/null || echo "") | |
| if [ -n "$ALL_PAGES" ]; then | |
| DELETED_COUNT=0 | |
| for page_id in $ALL_PAGES; do | |
| wp post delete "$page_id" --force 2>/dev/null | |
| DELETED_COUNT=$((DELETED_COUNT + 1)) | |
| done | |
| log "Alle Default-Pages gelöscht ($DELETED_COUNT Seite(n))" | |
| else | |
| log "Keine Default-Pages vorhanden" | |
| fi | |
| log "Default-Content erfolgreich aufgeräumt!" | |
| ############################################# | |
| # 9. STANDARD-THEMES ENTFERNEN | |
| ############################################# | |
| log "Entferne Standard-Themes..." | |
| # Liste aller Standard-Themes (twenty*) - nur inaktive | |
| STANDARD_THEMES=$(wp theme list --field=name --status=inactive | grep "^twenty" || true) | |
| if [ -z "$STANDARD_THEMES" ]; then | |
| warning "Keine inaktiven Standard-Themes zum Entfernen gefunden" | |
| else | |
| for theme in $STANDARD_THEMES; do | |
| wp theme delete "$theme" | |
| log "Theme '$theme' entfernt" | |
| done | |
| log "Standard-Themes erfolgreich entfernt!" | |
| fi | |
| ############################################# | |
| # 10. THEME FONTS & COLORS KONFIGURIEREN (OPTIONAL) | |
| ############################################# | |
| echo "" | |
| read -p "Möchtest du jetzt Fonts & Farben für dein Theme konfigurieren? (j/n) " -n 1 -r | |
| echo "" | |
| if [[ $REPLY =~ ^[Jj]$ ]]; then | |
| echo "" | |
| prompt "=== FARBEN KONFIGURIEREN ===" | |
| echo "" | |
| echo "Hinweis: Verwende Hex-Farben (z.B. #1f1f1f)" | |
| echo "" | |
| read -p "Black Farbe [#1f1f1f]: " COLOR_BLACK | |
| COLOR_BLACK=${COLOR_BLACK:-#1f1f1f} | |
| read -p "White Farbe [#ffffff]: " COLOR_WHITE | |
| COLOR_WHITE=${COLOR_WHITE:-#ffffff} | |
| read -p "Primary Farbe [#1c365b]: " COLOR_PRIMARY | |
| COLOR_PRIMARY=${COLOR_PRIMARY:-#1c365b} | |
| read -p "Secondary Farbe [$COLOR_PRIMARY]: " COLOR_SECONDARY | |
| COLOR_SECONDARY=${COLOR_SECONDARY:-$COLOR_PRIMARY} | |
| read -p "Light Background Farbe [#f7f7f7]: " COLOR_LIGHT_BG | |
| COLOR_LIGHT_BG=${COLOR_LIGHT_BG:-#f7f7f7} | |
| # Arrays für Standard-Farben | |
| declare -a COLOR_LABELS=("white" "black" "primary" "secondary" "light-background") | |
| declare -a COLOR_VALUES=("$COLOR_WHITE" "$COLOR_BLACK" "$COLOR_PRIMARY" "$COLOR_SECONDARY" "$COLOR_LIGHT_BG") | |
| # Zusätzliche Farben optional hinzufügen | |
| echo "" | |
| read -p "Möchtest du weitere Farben definieren? (j/n) " -n 1 -r | |
| echo "" | |
| if [[ $REPLY =~ ^[Jj]$ ]]; then | |
| while true; do | |
| echo "" | |
| read -p "Farb-Label (z.B. 'tertiary', 'accent', leer = fertig): " EXTRA_COLOR_LABEL | |
| # Abbruch wenn leer | |
| if [ -z "$EXTRA_COLOR_LABEL" ]; then | |
| break | |
| fi | |
| # Slug erstellen (lowercase, keine Sonderzeichen) | |
| EXTRA_COLOR_SLUG=$(echo "$EXTRA_COLOR_LABEL" | tr '[:upper:]' '[:lower:]' | tr ' ' '-') | |
| read -p "Hex-Farbe für '$EXTRA_COLOR_LABEL': " EXTRA_COLOR_VALUE | |
| # Validierung: Farbe muss mit # beginnen | |
| if [[ ! "$EXTRA_COLOR_VALUE" =~ ^#[0-9a-fA-F]{6,8}$ ]]; then | |
| warning "Ungültige Hex-Farbe: $EXTRA_COLOR_VALUE (Format: #1f1f1f)" | |
| continue | |
| fi | |
| # Zu Arrays hinzufügen | |
| COLOR_LABELS+=("$EXTRA_COLOR_SLUG") | |
| COLOR_VALUES+=("$EXTRA_COLOR_VALUE") | |
| log "✓ Farbe '$EXTRA_COLOR_LABEL' hinzugefügt: $EXTRA_COLOR_VALUE" | |
| done | |
| fi | |
| log "Aktualisiere Theme-Farben..." | |
| # SCSS Farben aktualisieren | |
| SCSS_FILE="wp-content/themes/$NEW_THEME_NAME/assets/css/_nxt-cheatsheet.scss" | |
| if [ -f "$SCSS_FILE" ]; then | |
| # Backup erstellen | |
| cp "$SCSS_FILE" "$SCSS_FILE.backup" | |
| # Aktualisiere alle definierten Farben | |
| for i in "${!COLOR_LABELS[@]}"; do | |
| label="${COLOR_LABELS[$i]}" | |
| value="${COLOR_VALUES[$i]}" | |
| # Versuche existierende Variable zu ersetzen | |
| if grep -q "^\$$label:" "$SCSS_FILE"; then | |
| sed -i "s/\$$label: #[0-9a-fA-F]\{6,8\};/\$$label: $value;/" "$SCSS_FILE" | |
| log " ✓ \$$label aktualisiert" | |
| else | |
| # Füge neue Variable nach der letzten Farb-Definition hinzu | |
| # Suche nach der letzten Zeile mit "$...: #..." | |
| last_color_line=$(grep -n '^\$[^:]*: #[0-9a-fA-F]' "$SCSS_FILE" | tail -1 | cut -d: -f1) | |
| if [ -n "$last_color_line" ]; then | |
| sed -i "${last_color_line}a\$$label: $value;" "$SCSS_FILE" | |
| log " ✓ \$$label neu hinzugefügt" | |
| fi | |
| fi | |
| done | |
| log "✓ SCSS Farben aktualisiert (Backup: $SCSS_FILE.backup)" | |
| fi | |
| # theme.json Farben aktualisieren | |
| THEME_JSON="wp-content/themes/$NEW_THEME_NAME/theme.json" | |
| if [ -f "$THEME_JSON" ]; then | |
| # Backup erstellen | |
| cp "$THEME_JSON" "$THEME_JSON.backup" | |
| # Python helper für sauberes JSON-Update mit allen Farben | |
| if command -v python3 &> /dev/null; then | |
| python3 << PYEOF | |
| import json | |
| # Farb-Arrays als Python-Listen | |
| labels = $(printf '%s\n' "${COLOR_LABELS[@]}" | python3 -c "import sys, json; print(json.dumps([line.strip() for line in sys.stdin]))") | |
| values = $(printf '%s\n' "${COLOR_VALUES[@]}" | python3 -c "import sys, json; print(json.dumps([line.strip() for line in sys.stdin]))") | |
| # theme.json laden | |
| with open('$THEME_JSON', 'r') as f: | |
| data = json.load(f) | |
| # Palette aktualisieren | |
| if 'settings' in data and 'color' in data['settings'] and 'palette' in data['settings']['color']: | |
| palette = data['settings']['color']['palette'] | |
| # Aktualisiere/Füge Farben hinzu | |
| for label, color_val in zip(labels, values): | |
| # Suche nach existierendem Eintrag | |
| found = False | |
| for item in palette: | |
| if item.get('slug') == label: | |
| item['color'] = color_val | |
| found = True | |
| break | |
| # Falls nicht gefunden, hinzufügen | |
| if not found: | |
| # Erstelle lesbaren Namen (capitalize, replace dashes) | |
| name = label.replace('-', ' ').title() | |
| palette.append({ | |
| "color": color_val, | |
| "name": name, | |
| "slug": label | |
| }) | |
| # Speichern | |
| with open('$THEME_JSON', 'w') as f: | |
| json.dump(data, f, indent=4) | |
| print("✓ theme.json Farben aktualisiert") | |
| PYEOF | |
| log "✓ theme.json Farben aktualisiert (Backup: $THEME_JSON.backup)" | |
| else | |
| warning "Python nicht verfügbar, theme.json manuell anpassen" | |
| fi | |
| fi | |
| ############################################# | |
| # GOOGLE FONTS HERUNTERLADEN | |
| ############################################# | |
| echo "" | |
| read -p "Möchtest du Google Fonts herunterladen? (DSGVO-konform lokal) (j/n) " -n 1 -r | |
| echo "" | |
| if [[ $REPLY =~ ^[Jj]$ ]]; then | |
| echo "" | |
| prompt "=== GOOGLE FONTS KONFIGURATION ===" | |
| echo "" | |
| echo "Beispiele: 'Open Sans', 'Roboto', 'Montserrat', 'Playfair Display'" | |
| echo "Weights: 400,700,400i (i = italic)" | |
| echo "" | |
| # Primary Font | |
| read -p "Primary Font Name [Open Sans]: " FONT_PRIMARY_NAME | |
| FONT_PRIMARY_NAME=${FONT_PRIMARY_NAME:-Open Sans} | |
| read -p "Primary Font Weights [400,700]: " FONT_PRIMARY_WEIGHTS | |
| FONT_PRIMARY_WEIGHTS=${FONT_PRIMARY_WEIGHTS:-400,700} | |
| # Secondary Font | |
| read -p "Secondary Font Name (leer lassen für Georgia Web-Safe): " FONT_SECONDARY_NAME | |
| FONT_SECONDARY_NAME=${FONT_SECONDARY_NAME:-Georgia} | |
| # Prüfe ob Georgia (Web-Safe Font) | |
| DOWNLOAD_SECONDARY=true | |
| if [ "$FONT_SECONDARY_NAME" = "Georgia" ]; then | |
| DOWNLOAD_SECONDARY=false | |
| FONT_SECONDARY_WEIGHTS="" | |
| log "Georgia ist eine Web-Safe Font und wird nicht heruntergeladen." | |
| else | |
| read -p "Secondary Font Weights [400,400i]: " FONT_SECONDARY_WEIGHTS | |
| FONT_SECONDARY_WEIGHTS=${FONT_SECONDARY_WEIGHTS:-400,400i} | |
| fi | |
| # Arrays für alle Fonts | |
| declare -a FONT_NAMES=("$FONT_PRIMARY_NAME" "$FONT_SECONDARY_NAME") | |
| declare -a FONT_WEIGHTS=("$FONT_PRIMARY_WEIGHTS" "$FONT_SECONDARY_WEIGHTS") | |
| declare -a FONT_DOWNLOAD=("true" "$DOWNLOAD_SECONDARY") | |
| # Zusätzliche Fonts optional hinzufügen | |
| echo "" | |
| read -p "Möchtest du weitere Fonts hinzufügen? (z.B. tertiary Font) (j/n) " -n 1 -r | |
| echo "" | |
| if [[ $REPLY =~ ^[Jj]$ ]]; then | |
| while true; do | |
| echo "" | |
| read -p "Font Name (z.B. 'Playfair Display', leer = fertig): " EXTRA_FONT_NAME | |
| # Abbruch wenn leer | |
| if [ -z "$EXTRA_FONT_NAME" ]; then | |
| break | |
| fi | |
| read -p "Font Weights für '$EXTRA_FONT_NAME' [400,700]: " EXTRA_FONT_WEIGHTS | |
| EXTRA_FONT_WEIGHTS=${EXTRA_FONT_WEIGHTS:-400,700} | |
| # Zu Arrays hinzufügen | |
| FONT_NAMES+=("$EXTRA_FONT_NAME") | |
| FONT_WEIGHTS+=("$EXTRA_FONT_WEIGHTS") | |
| FONT_DOWNLOAD+=("true") | |
| log "✓ Font '$EXTRA_FONT_NAME' hinzugefügt" | |
| done | |
| fi | |
| # Fonts-Verzeichnis erstellen | |
| FONTS_DIR="wp-content/themes/$NEW_THEME_NAME/assets/fonts" | |
| mkdir -p "$FONTS_DIR" | |
| log "Lade Google Fonts herunter (DSGVO-konform lokal)..." | |
| echo "" | |
| # Google Webfonts Helper API | |
| GWFH_API="https://gwfh.mranftl.com/api/fonts" | |
| # Array für alle Font-Faces (für theme.json später) | |
| declare -a ALL_FONT_FAMILIES=() | |
| ############################################# | |
| # ALLE FONTS HERUNTERLADEN (LOOP) | |
| ############################################# | |
| for idx in "${!FONT_NAMES[@]}"; do | |
| FONT_NAME="${FONT_NAMES[$idx]}" | |
| FONT_WEIGHT_LIST="${FONT_WEIGHTS[$idx]}" | |
| SHOULD_DOWNLOAD="${FONT_DOWNLOAD[$idx]}" | |
| # Slug erstellen | |
| FONT_SLUG=$(echo "$FONT_NAME" | tr '[:upper:]' '[:lower:]' | tr ' ' '-') | |
| # Skip Download für Georgia oder andere Web-Safe Fonts | |
| if [ "$SHOULD_DOWNLOAD" != "true" ]; then | |
| echo "" | |
| log "Font: $FONT_NAME (Web-Safe, kein Download nötig)" | |
| # Speichere Font-Family Daten für theme.json | |
| ALL_FONT_FAMILIES+=("{\"name\":\"$FONT_NAME\",\"slug\":\"$FONT_SLUG\",\"faces\":\"\"}") | |
| continue | |
| fi | |
| echo "" | |
| log "Font: $FONT_NAME" | |
| FONT_ID=$(echo "$FONT_NAME" | tr '[:upper:]' '[:lower:]' | tr ' ' '-') | |
| FONT_JSON=$(curl -s "${GWFH_API}/${FONT_ID}") | |
| if [ -z "$FONT_JSON" ] || [ "$FONT_JSON" = "null" ]; then | |
| warning "Font nicht gefunden: $FONT_NAME" | |
| warning "Stelle sicher, dass der Font-Name korrekt ist" | |
| ALL_FONT_FAMILIES+=("{\"name\":\"$FONT_NAME\",\"slug\":\"$FONT_SLUG\",\"faces\":\"\"}") | |
| continue | |
| fi | |
| FONT_FACES="" | |
| IFS=',' read -ra weights <<< "$FONT_WEIGHT_LIST" | |
| for weight in "${weights[@]}"; do | |
| weight=$(echo "$weight" | xargs) | |
| font_weight="$weight" | |
| font_style="normal" | |
| style_suffix="" | |
| variant_id="regular" | |
| # Bestimme Varianten-ID basierend auf Weight und Style | |
| if [[ "$weight" == *"i" ]]; then | |
| font_weight="${weight%i}" | |
| font_style="italic" | |
| style_suffix="-italic" | |
| if [ "$font_weight" = "400" ]; then | |
| variant_id="italic" | |
| else | |
| variant_id="${font_weight}italic" | |
| fi | |
| else | |
| if [ "$font_weight" = "400" ]; then | |
| variant_id="regular" | |
| else | |
| variant_id="$font_weight" | |
| fi | |
| fi | |
| filename="${FONT_SLUG}-${font_weight}${style_suffix}.woff2" | |
| # Extrahiere woff2 URL mit Python (falls verfügbar) oder grep | |
| if command -v python3 &> /dev/null; then | |
| woff2_url=$(python3 -c " | |
| import json, sys | |
| try: | |
| data = json.loads('''$FONT_JSON''') | |
| for variant in data.get('variants', []): | |
| if variant.get('id') == '$variant_id': | |
| print(variant.get('woff2', '')) | |
| sys.exit(0) | |
| except: | |
| pass | |
| " 2>/dev/null) | |
| else | |
| # Fallback ohne Python - einfaches grep | |
| woff2_url=$(echo "$FONT_JSON" | grep -A10 "\"id\":\"$variant_id\"" | grep -o '"woff2":"[^"]*"' | cut -d'"' -f4) | |
| fi | |
| if [ -n "$woff2_url" ]; then | |
| if curl -s -L -o "$FONTS_DIR/$filename" "$woff2_url"; then | |
| # Prüfe ob Datei tatsächlich heruntergeladen wurde | |
| if [ -f "$FONTS_DIR/$filename" ] && [ -s "$FONTS_DIR/$filename" ]; then | |
| log " ✓ $filename ($font_weight $font_style)" | |
| FONT_FACES+="$filename|$font_weight|$font_style;" | |
| else | |
| warning " ✗ Download fehlgeschlagen (leere Datei): $filename" | |
| rm -f "$FONTS_DIR/$filename" | |
| fi | |
| else | |
| warning " ✗ Download fehlgeschlagen: $filename" | |
| fi | |
| else | |
| warning " ✗ Variante nicht gefunden: $variant_id ($font_weight $font_style)" | |
| fi | |
| done | |
| # Speichere Font-Family Daten für theme.json | |
| ALL_FONT_FAMILIES+=("{\"name\":\"$FONT_NAME\",\"slug\":\"$FONT_SLUG\",\"faces\":\"$FONT_FACES\"}") | |
| done | |
| # SCSS Font-Stacks aktualisieren | |
| echo "" | |
| log "Aktualisiere SCSS Font-Stacks..." | |
| SCSS_FILE="wp-content/themes/$NEW_THEME_NAME/assets/css/_nxt-cheatsheet.scss" | |
| if [ -f "$SCSS_FILE" ]; then | |
| # Backup erstellen | |
| cp "$SCSS_FILE" "$SCSS_FILE.backup" | |
| # Primary & Secondary Font (wenn vorhanden) | |
| if [ ${#FONT_NAMES[@]} -ge 1 ]; then | |
| sed -i "s/\$font-stack: '[^']*'/\$font-stack: '${FONT_NAMES[0]}'/" "$SCSS_FILE" | |
| fi | |
| if [ ${#FONT_NAMES[@]} -ge 2 ]; then | |
| sed -i "s/\$serif-font: '[^']*'/\$serif-font: '${FONT_NAMES[1]}'/" "$SCSS_FILE" | |
| fi | |
| log "✓ SCSS Font-Stacks aktualisiert (Backup: $SCSS_FILE.backup)" | |
| fi | |
| # theme.json Font-Faces aktualisieren | |
| log "Aktualisiere theme.json Font-Faces..." | |
| if [ -f "$THEME_JSON" ] && command -v python3 &> /dev/null; then | |
| # Backup erstellen | |
| cp "$THEME_JSON" "$THEME_JSON.backup" | |
| # Konvertiere Bash Array zu Python-kompatiblem Format | |
| FONT_FAMILIES_JSON="[" | |
| for font_data in "${ALL_FONT_FAMILIES[@]}"; do | |
| FONT_FAMILIES_JSON+="$font_data," | |
| done | |
| FONT_FAMILIES_JSON="${FONT_FAMILIES_JSON%,}]" # Remove trailing comma | |
| python3 << PYEOF | |
| import json | |
| # Font-Family Daten aus Bash | |
| font_families_raw = $FONT_FAMILIES_JSON | |
| # Fonts JSON generieren | |
| def create_fontface(font_data): | |
| font_name = font_data['name'] | |
| font_slug = font_data['slug'] | |
| faces_str = font_data['faces'] | |
| # Bestimme Fallback basierend auf Font-Name | |
| if 'serif' in font_name.lower() or font_name == 'Georgia': | |
| fallback = "Georgia, 'Times New Roman', Times, serif" | |
| else: | |
| fallback = "Arial, sans-serif" | |
| faces = [] | |
| # Georgia oder leere faces (Web-Safe Font) | |
| if font_name == "Georgia" or not faces_str: | |
| return { | |
| "fontFamily": f"{font_name}, {fallback}", | |
| "name": font_name, | |
| "slug": font_slug | |
| } | |
| # Normale Fonts mit @font-face | |
| for face in faces_str.rstrip(';').split(';'): | |
| if not face: | |
| continue | |
| parts = face.split('|') | |
| if len(parts) == 3: | |
| filename, weight, style = parts | |
| faces.append({ | |
| "fontFamily": font_name, | |
| "fontStyle": style, | |
| "fontWeight": weight, | |
| "src": [f"file:./assets/fonts/{filename}"] | |
| }) | |
| if faces: | |
| return { | |
| "fontFace": faces, | |
| "fontFamily": f"'{font_name}', {fallback}", | |
| "name": font_name, | |
| "slug": font_slug | |
| } | |
| else: | |
| return { | |
| "fontFamily": f"{font_name}, {fallback}", | |
| "name": font_name, | |
| "slug": font_slug | |
| } | |
| # theme.json laden | |
| with open('$THEME_JSON', 'r') as f: | |
| data = json.load(f) | |
| # Alle Font Families erstellen | |
| all_fonts = [create_fontface(font_data) for font_data in font_families_raw] | |
| # Fonts in theme.json einfügen | |
| if 'settings' in data and 'typography' in data['settings']: | |
| data['settings']['typography']['fontFamilies'] = all_fonts | |
| # Default Font Family in styles.typography setzen (erste Font) | |
| if all_fonts and 'styles' in data and 'typography' in data['styles']: | |
| data['styles']['typography']['fontFamily'] = f"var(--wp--preset--font-family--{all_fonts[0]['slug']})" | |
| # Speichern | |
| with open('$THEME_JSON', 'w') as f: | |
| json.dump(data, f, indent=4) | |
| print("✓ theme.json Font-Faces aktualisiert") | |
| if all_fonts: | |
| print(f"✓ Default Font Family gesetzt auf: {all_fonts[0]['slug']}") | |
| print(f"✓ {len(all_fonts)} Font(s) konfiguriert") | |
| PYEOF | |
| log "✓ theme.json Font-Faces aktualisiert (Backup: $THEME_JSON.backup)" | |
| else | |
| if [ ! -f "$THEME_JSON" ]; then | |
| warning "theme.json nicht gefunden: $THEME_JSON" | |
| elif ! command -v python3 &> /dev/null; then | |
| warning "Python3 nicht verfügbar, theme.json Font-Faces manuell anpassen" | |
| fi | |
| fi | |
| log "Google Fonts erfolgreich heruntergeladen und konfiguriert!" | |
| fi | |
| fi | |
| echo "" | |
| log "=== Installation abgeschlossen! ===" | |
| echo "" | |
| echo "URL: $WP_URL" | |
| echo "Admin User: $WP_ADMIN_USER" | |
| echo "Admin Passwort: $WP_ADMIN_PASSWORD" | |
| echo "Theme: $NEW_THEME_NAME (von GitHub)" | |
| echo "" | |
| echo "Hinweis: Kompiliere dein SCSS zu CSS um Farb-Änderungen zu sehen!" | |
| echo "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment