
Pewnie niektórzy są juz lekko zmęczeni tematem migracji bloga z Wordpressa do Jekylla. Z drugiej strony, sporo osób prosiło mnie o opisanie, w jaki sposób przeprowadziłem się z jednej z tych platform na drugą. Postanowiłem więc, że spełnię te prośby i tym samym raz na zawsze zamkniemy ten temat! Początkowo planowałem opisać całość “za jednym zamachem” ale okazało się, że opis samej tylko migracji danych z Wordpressa do Jekylla to prawie 2 tysiące słów. Dlatego też, temat został podzielony na dwie części: dziś opisuję jak przeniosłem posty i całą resztę do Jekylla, natomiast za tydzień przedstawię jak przeprowadziłem deployment do Heroku!

Migracja bloga #1: Wordpress → Jekyll, krok po kroku!
Pewnie niektórzy są juz lekko zmęczeni tematem migracji bloga z Wordpressa do Jekylla. Z drugiej strony, sporo osób prosiło mnie o opisanie, w jaki sposób przeprowadziłem się z jednej z tych platform na drugą. Postanowiłem więc, że spełnię te prośby i tym samym raz na zawsze zamkniemy ten temat! Początkowo planowałem opisać całość “za jednym zamachem” ale okazało się, że opis samej tylko migracji danych z Wordpressa do Jekylla to prawie 2 tysiące słów. Dlatego też, temat został podzielony na dwie części: dziś opisuję jak przeniosłem posty i całą resztę do Jekylla, natomiast za tydzień przedstawię jak przeprowadziłem deployment do Heroku!
Migracja Wordpress - Jekyll
Zanim rozpocząłem operację przeniesienia wszystkich wpisów, stron itd., do Jekylla, trzeba było najpierw przeprowadzić jego instalację, utworzyć repozytorium na GitHubie i jeszcze parę innych rzeczy. Poniżej opisuję te kroki bardziej szczegółowo.
Instalacja Jekylla
Przenosiny na Jekylla rozpocząłem oczywiście od jego instalacji. Jeśli masz już wcześniej zainstalowane Ruby (ja miałem, jeśli Ty nie masz to musisz sprawdzić jak to zrobić w Twoim systemie operacyjnym) to wystarczy wykorzystać RubyGems, czyli menedżer pakietów Ruby:
gem install jekyll
Powyższe zainstaluje Ci Jekylla w najnowszej stabilnej wersji. Jak się później okazało, w moim przypadku konieczne było użycie tej komendy z dodatkowym parametrem:
gem install jekyll --pre
W ten sposób zainstalowałem sobie wersję “pre-release” (w chwili pisania tego tekstu jest to wersja 3.6.0.pre.beta1
). Dlaczego? Ano dlatego, że kluczowe było dla mnie prawidłowe kolorowanie składni JSX, czego nigdy nie udało mi się zrobić w Wordpressie.
Do tego celu potrzebowałem odpowiedniej wersji biblioteki Rouge, która odpowiada za kolorowanie składni w Jekyllu (obsługa JSX pojawiła się w wersji 2.0.6 tej biblioteki). Niestety, stabilna wersja Jekylla używa biblioteki Rouge w znacznie starszej wersji i jest to zależność wymagana. Próba instalacji nowszej wersji Rouge i usunięcie wersji wymaganej (można mieć zainstalowane kilka wersji danego “gema” jednocześnie) powodowało błąd.
Dopiero we wspomnianej wersji 3.6.0 Jekylla dodano możliwość użycia biblioteki Rouge w najnowszej wersji, postanowiłem więc, że póki co skorzystam z wersji “pre-release”, oczywiście do czasu aż stanie się ona wersją stabilną.
Konfiguracja Jekylla
Po zainstalowaniu Jekylla mogłem przystąpić do jego konfiguracji. Praktycznie wszystko możemy ustawić edytując plik _config.yml
. Myślę, że nie ma sensu abym wdawał się w szczegóły konfiguracyjne - to każdy może sobie sprawdzić w dokumentacji Jekylla.
W tym miejscu dodam tylko, że na tę chwilę korzystam tylko z trzech wtyczek dla Jekylla (to się być może zmieni w przyszłości). Pluginy te to:
jekyll-feed
jekyll-sitemap
jekyll-twitter-plugin
Co robią dwa pierwsze jest raczej oczywiste. Trzeci z nich usprawnia lekko proces osadzania tweetów.
Bundler i Gemfile
Oprócz konfiguracji w pliku _config.yml
warto też używać narzędzia o wdzięcznej nazwie Bundler. Pozwala ono na kontrolę i instalację właściwych wersji poszczególnych “gemów” oraz ich zależności.
Bundlera instalujemy standardowo:
gem install bundler
Następnie należy dodać do głównego katalogu projektu plik Gemfile
, w którym definiujemy wszystkie wymagane przez nasz projekt zależności - jest to więc swoisty odpowiednik pliku package.json
znany nam z npm. W moim przypadku, plik ten wygląda następująco (w momencie pisania tego tekstu):
source 'https://rubygems.org'
ruby '2.4.1'
gem 'jekyll', '3.6.0.pre.beta1'
gem 'json'
# plugins
gem 'jekyll-sitemap'
gem 'jekyll-twitter-plugin'
# for deployment
gem 'rack-rewrite'
gem 'rack-contrib'
gem 'rake'
gem 'puma'
group :jekyll_plugins do
gem "jekyll-feed", "~> 0.6"
end
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
Część powyższych zależności dodana została później, na potrzeby deploymentu do Heroku. Omówię je w kolejnej części artykułu.
Posiadając zainstalowane narzędzie Bundler oraz utworzony plik Gemfile
zawierający wymagane przez nasz projekt zależności, możemy uruchomić polecenie:
bundle install
Spowoduje ono instalację wszystkich niezbędnych pakietów zdefiniowanych w pliku Gemfile
wraz z ich zależnościami. Oprócz tego utworzony zostanie plik Gemfile.lock
, w którym Bundler zapisuje dokładne wersje zainstalowanych pakietów. Dzięki temu, jeśli wywołamy polecenie bundle install
na innej maszynie, zostaną na niej zainstalowane dokładnie te same wersje pakietów co u nas.
Uwaga! Powyższe kroki będą niezbędne w późniejszym procesie deploymentu!
Szablon
Jekyll instalowany jest wraz z domyślnym szablonem o nazwie Minima. Oczywiście od początku wiedziałem, że nie chcę z niego korzystać tylko stworzyć swój własny szablon.
Minima
jest szablonem opartym o “gemy” (w dokumentacji jest to nazwane z angielska “gem-based”). Oznacza to, że szablon ten jest osobnym pakietem, który można zainstalować za pomocą menedżera pakietów Ruby (wspomniane wcześniej RubyGems). Ja natomiast wolałem mieć pełną kontrolę nad szablonem w ramach mojego bloga.
Dlatego też, po przestudiowaniu dokumentacji Jekylla dotyczącej szablonów, usunąłem odwołania do szablonu Minima
z plików Gemfile
oraz _config.yml
. Następnie, dla ułatwienia, przeniosłem zawartość szablonu Minima
do głównego katalogu projektu bloga. Dzięki temu, mogłem sprawdzić jak ten szablon działa i na jego podstawie, modyfikując odpowiednie pliki, stworzyć własny wygląd bloga.
Dodatkowo, skonfigurowałem sobie webpacka i ustawiłem wszystko tak, aby generowały się osobne “bundle” zawierające kod JavaScript specyficzny dla danego typu strony (posty, podstrony). Do tego oczywiście jeden “bundle” dla vendors
oraz jeden, o nazwie common
zawierający kod współdzielony przez wszystkie typy stron.
Na tę chwilę webpackiem “ogarniam” tylko kod JavaScript, ponieważ Jekyll ma wbudowaną obsługę Sass. Planuję jednak przerobić to tak, aby style również były “traktowane” webpackiem. Dzięki temu uzyskam lepszą optymalizację wynikowego kodu CSS, a przy okazji pewnie zamiast Sass’a zastosuję mój ulubiony Stylus…
Repozytorium na GitHubie
Po zainstalowaniu i skonfigurowaniu Jekylla, utworzyłem repozytorium na GitHubie, w którym będę trzymać cały projekt wraz z wpisami, obrazkami itp. Jest to repozytorium prywatne więc nie podaję do niego linka…
W tym miejscu warto wspomnieć, które pliki i katalogi dodałem do ignorowanych, tak aby nie wysyłały się one na serwer. Oto zawartość mojego pliku .gitignore
w chwili pisania tego tekstu:
.sass-cache
.tweet-cache
.jekyll-metadata
_site
node_modules
assets/scripts
Trzy pierwsze wpisy to katalogi ukryte, tworzone podczas generowania strony przez Jekylla lub przez wtyczki (tutaj jekyll-twitter-plugin
). Obecności wśród ignorowanych katalogu node_modules
zapewne nie muszę Ci wyjaśniać.
Najważniejszy wpis to _site
. Jego obecność tutaj wynika bezpośrednio z tego jak działa Jekyll. Otóż praca z nim wygląda w następujący sposób: do odpowiednich katalogów dodajemy posty oraz podstrony bloga (w formacie Markdown); następnie uruchamiamy polecenie:
jekyll build
Powoduje ono, że Jekyll przegląda katalogi naszego projektu, na tej podstawie generuje statyczne strony HTML, a wszystko w rezultacie ląduje w katalogu _site
. Ten katalog następnie powinien być “serwowany” przez serwer WWW. Jak więc widać, jest to katalog generowany za każdym razem gdy coś zmienimy w naszym projekcie, nie ma więc sensu go wrzucać do repozytorium.
Uwaga! Dopilnuj, aby do repozytorium trafiły też pliki
Gemfile
orazGemfile.lock
!
Przeniesienie danych z Wordpressa
Ok, Jekyll jest już w zasadzie skonfigurowany i umieszczony w repozytorium na GitHubie. Teraz nadeszła pora na najtrudniejszą część procesu czyli przeniesienie wpisów i podstron (wraz ze zdjęciami itp.) z Wordpressa do Jekylla.
Eksport danych z Wordpressa
Do eksportu danych w Wordpressa użyłem standardowej metody eksportu do formatu XML, jaki dostępny jest w menu Narzędzia
→ Export
tego CMS’a. Początkowo wybrałem opcję eksportu wszystkich treści ale po zaimportowaniu ich do Jekylla okazało się, że jest tego wszystkiego trochę za dużo.
Celem tej migracji było uproszczenie mojego bloga, nie potrzebowałem więc podstron typu “Kontakt” i wielu innych. Z tego względu postanowiłem przeprowadzić operację jeszcze raz i tym razem wyeksportowałem tylko posty, z zamiarem ręcznego przeniesienia treści podstron, które będę chciał mieć w nowym blogu.
Import danych do Jekylla
Importu wyeksportowanych wcześniej z Wordpressa postów dokonałem z użyciem metody zalecanej w dokumentacji Jekylla dla migracji z platformy wordpress.com. Do tego celu potrzebowałem narzędzia jekyll-import
, które zainstalowałem następująco:
gem install jekyll-import
Pakietu tego nie trzeba dodawać do pliku Gemfile
, ponieważ użyjemy go tylko raz, w celu importu. Kolejna rzecz, to uruchomienie procesu importu (wyeksportowane dane znajdują się w pliku nafrontendzie_posty.xml
):
ruby -rubygems -e 'require "jekyll-import";
JekyllImport::Importers::WordpressDotCom.run({
"source" => "nafrontendzie_posty.xml"
})'
Po zakończeniu działania powyższej komendy, w katalogu _posts
znajdują się wszystkie wpisy wyeksportowane z Wordpressa. Oczywiście zawierają one metadane niezbędne dla Jekylla, takie jak autor, tytuł, data publikacji itp. Oprócz tego, do katalogu assets
trafiły wszystkie obrazki użyte w treści postów. Niestety… Nie wszystko jest tak idealnie jakbyśmy tego chcieli…
Po pierwsze, posty zaimportowały się w formacie *.html
, a nie *.md
(Jekyll radzi sobie dobrze z obiema formami). W zasadzie można to tak zostawić i dopiero nowe posty tworzyć z użyciem składni Markdown, ja jednak postanowiłem to sobie przekonwertować (o tym za moment).
Po drugie, tak jak napisałem powyżej, obrazki się zaimportowały ale tylko te, które znajdują się w treści wpisów. W Wordpressie natomiast jest coś takiego jak “featured image” (po naszemu “obrazek wyróżniający”) czego standardowo nie ma w Jekyllu. Tutaj niestety musiałem sobie poradzić “ręcznie” i o tym również za chwilę.
Konwersja postów w HTML do Markdown
Do skonwertowania postów w formacie HTML do Markdown użyłem skryptu JavaScript znalezionego w tym repozytorium. Znajdziesz w nim plik index.js
, który zawiera cały niezbędny kod.
Zawartość tego pliku skopiowałem do pliku convert.js
, który umieściłem w głównym katalogu bloga. Wymaga on jednej zależności: html-md
, którą tymczasowo zainstalowałem za pomocą yarn
:
yarn add html-md
Teraz wystarczyło tylko uruchomić skrypt z pomocą Node.js:
node ./convert.js
I voilà! W katalogu _posts
znajdują się teraz pliki *.md
, natomiast oryginalne pliki HTML zostały przeniesione do katalogu _posts_html
(po sprawdzeniu czy wszystko jest ok, można je bezpiecznie usunąć).
Obrazki wyróżniające
Tutaj niestety było więcej roboty, którą pewnie dałoby się jakoś zautomatyzować. Nie znalazłem jednak do tego żadnego gotowca, postanowiłem więc, że przeniosę wszystko ręcznie.
Ogólnie moje podejście wyglądało tak (rozwiązanie podsunął mi jakiś blog post znaleziony w internecie):
- dla każdego z postów pobrałem odpowiednie zdjęcie ze starego bloga i umieściłem je w podkatalogu
featured
folderuassets
- każdy wpis w Jekyllu zawiera metadane, w których umieściłem dodatkowe ustawienie
image
i przypisałem do niego ścieżkę do odpowiedniego pliku graficznego
Przykładowe metadane wyglądają tak:
---
layout: post
title: Na Frontendzie od nowa!
date: 2017-09-18 07:30:00 +02:00
type: post
published: true
status: publish
categories:
- opinie
tags: []
image: /assets/featured/Depositphotos_5868057_original.jpg
full: true
author:
login: burczu
email: b.dybowski@gmail.com
display_name: Bartek Dybowski
first_name: Bartek
last_name: Dybowski
---
Teraz wystarczyło tylko wykorzystać zapisany w ten sposób link w szablonie. Mamy tam do niego dostęp poprzez zmienną page
:
<img class="post-header__image" src="/assets/featured/{{ page.image }}" alt="Featured image of the post" />
Napisałem sobie też skrypt, który odpowiada za przycinanie i optymalizację tych obrazków, ale to jest temat na osobny wpis. Jeśli jesteś tym zainteresowany daj znać w komentarzach lub w prywatnej wiadomości, a być może przedstawię go w przyszłości na blogu!
Ostatnie szlify przed publikacją
W tym momencie najważniejsze rzeczy miałem już w zasadzie zrobione: posty zaimportowane wraz ze zdjęciami, szablon przygotowany, wszystko działa jak należy.
Pozostało jedynie utworzenie podstron “O mnie” oraz “Szkolenia”, które celowo pominąłem przy eksporcie (pisałem o tym wyżej). W Jekyllu mamy dwa sposoby na utworzenie takich podstron (więcej w dokumentacji).
Pierwszy z nich to umieszczenie odpowiednich plików w głównym katalogu projektu. W tym przypadku, nazwa pliku staje się jego adresem - na przykład plik o-mnie.md
będzie dostępny pod adresem /o-mnie
.
Drugi, bardziej odpowiadający mi sposób to trzymanie podstron w podkatalogu, który nazwałem pages
. W takim przypadku, metadane każdego z plików podstron muszą zawierać właściwość permalink
, która definiuje pod jakim adresem będzie dostępna dana podstrona. Dla przykładu, oto metadane podstrony o-mnie
(plik about.md
) na moim blogu:
---
layout: page
title: Więcej o mnie i o blogu
permalink: /o-mnie/
description: Na tej stronie przedstawiam parę słów o mnie. Skąd przychodzę, dokąd zmierzam... Dowiesz się z niej również co nieco o tym blogu!
---
Podsumowanie
To w zasadzie tyle jeśli chodzi o przeniesienie danych z Wordpressa do Jekylla. Tak jak napisałem na wstępie, w kolejnej części przedstawię, w jaki sposób skonfigurowałem deployment bloga na serwery Heroku.
P.S. Jeśli coś jest niejasne, opisane za mało szczegółowo albo coś ewidentnie pominąłem, daj znać w komentarzu, a postaram się uzupełnić braki!