Skip to content

Migracja z Wordpress do AstroJS

Posted on: 22 grudnia 2023  at  11:30
Reading Time: 6 min czytania
Feature Image for  Migracja z Wordpress do AstroJS

Motywacja

Nad zmianą myślałem od dłuższego czasu, ale zawsze było ALE. Co prawda, o powodach zmian i ich konsekwencjach pisałem w tej notatce ↗, ale uzupełnię ją cytatem, który znalazłem u Lei Verou ↗:

It was time to move on. It’s not you WP, it’s me.

Czas i na mnie.

Statyczne strony

W moim czytniku RSS jest sporo statycznie generowanie blogów, imponujące szybkością, prostotą i co najważniejsze: nie było żadnych różnić w stosunku do blogów, opartych na WP. Stąd też wydawało się oczywiste, iż przejście na tego typu “silnik” jest kolejnym krokiem milowym w mojej wieloletniej karierze Blogera. No i wreszcie zrealizowałem jedno z wielu celów, jakie wytyczyłem na ten rok — lepiej późno niż wcale.

Proces tworzenia i publikacji notatek jest naprawdę uproszczony do minimum, co prawda jeszcze nie jest w pełni zautomatyzowany, ale już teraz działa tak, jak przewidywałem.

Czyli

Automatyczny deploy

Tak, brakuje tutaj automatycznego deploy, który zadziałałby po przesłaniu zmian do gałęzi master projektu w repozytorium. Świadomie ten krok pominąłem z uwagi na wielkość projektu, przekraczający przeszło 1 GB (wszelkie zdjęcia i ilustracje do wpisów), co ma negatywny wpływ na limit czasowy, jaki obowiązuje w większości CI/CD.

Mam kilka pomysłów na optymalizację, więc w najbliższej przyszłości będę to sprawdzał.

✅ Udało się dzięki Wiktorowi ↗, który podsunął pomysł na wykorzystanie GitLab Runner.

Migracja treści do Markdown

Skoro istnieją odpowiednie narzędzia, to proces migracji wydawał się dość prosty. Jak się potem okazało, to był najbardziej upierdliwy i czasochłonny etap pracy.

Narzędzie do eksportu WordPress

Z pomocą przychodzi projekt WordPress export to Markdown ↗, Jest to skrypt konwertujący plik XML (wyeksportowany z WordPress) do plików Markdown odpowiednich dla większości znanych generatorów stron statycznych.

Każdy post jest zapisywany jako oddzielny plik Markdown z odpowiednią treścią. Obrazy są również pobierane i zapisywane. Osadzone treści z YouTube, Twittera, CodePen itp. są starannie zachowywane.

Własny fork - dostosowany do wymogów AstroJS

Okazało się, ze domyślne opcje ww. eksportera nie są zgodne z tymi, które stosuje sie zazwyczaj AstroJS (a konkretnie w AstroPaper | Astro ↗).

Po przejrzeniu listy zgłoszeń i zmian w repo projektu, utworzyłem własny projekt ↗ ( baza wiadoma), wprowadzając modyfikacje własne i innych:

Osiągnąłem strukturę pliku .md, zgodną z schematem AstroJS,

---
title: ""
postSlug: ""
pubDatetime: ""
categories:
  - ""
  - ""
tags:
  - ""
  - ""
  - ""
description: ""
series: ""
coverImage: "https://static.bobiko.blog/2023/12/migracja-wordpress-astro/images/astrojs.png"
wp_id: "--"
wp_slug: ""
wp_type: "post"
---

Content ...

Dalsze komplikacje

Ignorancja kosztuje

Sam eksport nie wymagał mojej uwagi, zatem działał w tle, łącznie z pobraniem plików graficznych. Finalnie komunikat wyglądał właśnie tak:

Informacje o 251 plikach zignorowałem, bo uznałem to za małą istotne dla bloga (zwłaszcza, ze powstały ponad 12-15 lat temu).

Jak się potem okazało, musiałem osunąć te błędne ścieżki z wpisy, bo w trakcie build sypało wyjątkami. Ignorancja kosztuje

Ścieżki grafik

Pierwsze podejście uruchomienia projektu zakończyło się niepowodzeniem, ponieważ ścieżki plików były złe - wskazywały na katalog /public/images/* (ścieżka absolutna) zamiast /dist/blog/2023-12/images/* (ścieżka lokalna) Ten sam błąd wystąpił w przypadku metadanych coverImage

Rozwiązanie: zmiana ścieżki images/image.jpg na ./images/image.jpg. Niby niewielka różnica, ale konsekwencje ogromne.

Polskie znaki w nazwie plików

Dotąd nie wiem, dlaczego pozwoliłem na polskie ogonki, spacje etc. w nazwach plików. Skoro WordPress nie widział w tym nic szczególnego, to czemu miałbym się tym przejmować? Otóż AstroJS ma jaką dziwną manierę ze wszelkie niedozwolone znaki zamieniał na ich odpowiedniki z ASCII a nazwa plików pozostała bez zmian.

Napisałem z niewielką pomocą AI taki oto konwerter w Bash:

#!/bin/bash

if [ -z "$1" ]; then
  echo "Podaj katalog główny jako parametr"
  exit 1
fi
cd "$1" || exit 2

echo "stara nazwa | nowa nazwa" > zmiany.csv


find . -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.gif" \) | while read -r file; do

  filename=$(basename -- "$file")
  # Zamień polskie znaki diakrytyczne na ich odpowiedniki bez ogonków, używając polecenia iconv z kodowaniem ASCII//TRANSLIT
  newname=$(echo "$filename" | iconv -f UTF-8 -t ASCII//TRANSLIT)
  # Jeśli nazwa pliku się zmieniła, to
  if [ "$filename" != "$newname" ]; then
    # Zapisz zmianę do pliku csv, używając tylko ./images/<nazwa pliku> jako ścieżki
    echo "./images/$filename | ./images/$newname" >> zmiany.csv
    # Zmień nazwę pliku graficznego
    mv -- "$file" "${file%/*}/$newname"
    # Wypisz na ekranie informację o zmianie nazwy pliku graficznego
    echo "Zmieniono nazwę pliku graficznego: $file -> ${file%/*}/$newname"
    # Znajdź plik index.md w katalogu poziom wyżej od katalogu z grafiką
    mdfile="${file%/*/*}/index.md"
    # Jeśli plik index.md istnieje, to
    if [ -f "$mdfile" ]; then
      # Zmień ścieżkę pliku graficznego w treści pliku index.md, używając tylko ./images/<nazwa pliku> jako ścieżki
      sed -i "s/(.\/images\/$filename)/(.\/images\/$newname)/g" "$mdfile"
      # Wypisz na ekranie informację o zmianie ścieżki pliku graficznego w pliku index.md
      echo "Zmieniono ścieżkę pliku graficznego w pliku index.md: $mdfile"
    fi
  fi
done

w ten sposób miałem listę plików do zamiany. Napisałem drugi skrypt, zamieniający ścieżki w plikach MD i sprawiło, szybko przywróciłem poprzedni stan. Okazało się, że niepoprawnie wykrywały odpowiedniki z tablicy ASCII. Lista zmian nie była na tyle duża, wiec ten etap zrobiłem po prostu ręcznie.

Dziwne znaki

Pojawiły się kolejne błędy, jakie pojawiły się w trakcie budowania w AstroJS.

\-
\*
\'

Tego typu błędy pojawiały się głównie tam, gdzie była lista. To chyba jakiś nieoczekiwany błąd, wyjątek, z którym nie poradził sobie eksporter.

Wszędzie pułapki.

Czas publikacji

O ile Hugo czy Jekyll dość łaskawie podchodzą do czasu publikacji wpisu, ograniczając się do formatu YYYY-MM-DD, tak w AstroJS jest wymagany datę i godzinę w formacie ISO 8601 (czyli obiekt Date() w JS).

Przy eksporcie nie ma z tym największego problemu, ale nieświadomie popełniłem błąd, zapisując atrybut pubDatetime jako string, co było niezgodne z schematem struktury w AstroJS. Łopatologicznie rzecz biorąc: chodziło o to, ze 2023-12-18T17:30:45.000Z powinien być bez cudzysłowie.

Rozwiązanie było proste: konwersja string na obiekt Datetime przy użyciu biblioteki Zod:

{
    pubDatetime: z.string().transform(str => new Date(str) ),
}

Struktura linków

Pierwsze wersje bloga miały dziwaczną strukturę linków

https://bobiko.blog/posts/YYYY-MM/<nazwa>

co odzwierciedlało strukturę w projekcie:

├── posts
│   ├── index.astro
│   └── [slug]
│       ├── index.astro
│       └── index.png.ts

Początkowo myślałem o przekierowaniach w plikach .htaccess, ale konsekwencje byłyby ogromne — z uwagi na 16 lat blogowania.

Poszperałem i znalazłem info / wzmiankę (tylko już nie pamiętam gdzie), że aby usunać posts z URL, należy skorzystać z operatora spread

├── posts
│   ├── index.astro
│   └── [...slug]
│       ├── index.astro
│       └── index.png.ts

Zapis [...posts] pozwala na rozbicie iterowanego obiektu z postami na pojedyncze posty.

Ostatecznie .htacces wykorzystałem do przekierowania:

Co dalej?

Jestem zadowolony z efektów wielodniowej pracy nad zmianą, dostarczając całkiem niezłą dawkę wiedzy (i frustracji także). Sprawiła, że poznałem bliżej AstroJS (wady i zalety), widzę spory potencjał na nowe strony w najbliższej przyszłość; najbardziej cenię fakt, że mogę pisać równie mikrokomponenty w Next.js obok Vue czy Svelte.

Wracając do pytania, to sporo pracy czeka na mnie:

Dziękuję za każdy feedback (w większości bardzo pozytywny), co tylko utwierdza mnie w przekonaniu, że była to dobra decyzja ❤️

Uff. ale się rozpisałem ;-).



Możesz napisać do mnie e-mail lub wyszukać mnie na Mastodonie.