Dokumentacja
M 404 Handler
M 404 Handler to menedżer przekierowań i zestaw narzędzi do obsługi błędów 404 w WordPressie: nieograniczona liczba reguł z wybranym kodem statusu i trybem dopasowania, dziennik martwych linków grupowany według adresu oraz możliwość wyświetlenia prawdziwej strony WordPressa jako odpowiedzi na błąd 404. Wtyczka powstała z myślą o administratorze, który właśnie przeniósł albo przebudował witrynę i chce, żeby stare adresy dalej działały. Na froncie nie ładuje się ani jeden plik, a żaden błąd 404 nie jest nigdzie przekierowywany, dopóki sam nie włączysz trybu zastępczego. Dwóch fragmentów tej instrukcji nie da się pominąć: szerokie reguły obejmują REST API, a więc i edytor blokowy, a dwóch ustawień w ogóle nie da się zapisać z ekranu Settings.
Instalacja i aktywacja
M 404 Handler instaluje się jak każda inna wtyczka WordPressa. Wymaga WordPressa 6.0 i PHP 7.4 lub nowszego, nie wymaga konta, klucza licencyjnego ani żadnej usługi zewnętrznej. Aktywacja tworzy tabele w bazie i zapisuje ustawienia domyślne, ale nie zmienia niczego, co widzą odwiedzający.
- Wgraj folder wtyczki do /wp-content/plugins/ albo zainstaluj plik ZIP przez Wtyczki, Dodaj nową wtyczkę, Wyślij wtyczkę na serwer.
- Aktywuj ją na ekranie Wtyczki. W sieci multisite aktywacja dla całej sieci tworzy tabele na każdej istniejącej witrynie, a witryny utworzone później dostają je automatycznie. Ta pętla wykonuje się w jednym żądaniu aktywacji i nie ogranicza liczby witryn, więc w dużej sieci może przerwać się w połowie; witryny, do których nie dotarła, tworzą sobie tabele przy najbliższym załadowaniu strony, a do tego czasu ich reguły nie działają.
- Otwórz nowe menu 404 Handler w panelu administracyjnym. W wierszu wtyczki na ekranie Wtyczki pojawiają się też dwa skróty: Redirects i Settings.
- Powstają dwie tabele: wp_m404_redirects i wp_m404_404_log, z twoim własnym prefiksem zamiast wp_.
- Tworzona jest autoładowana opcja m404_settings z ustawieniami domyślnymi, a obok niej m404_rule_counts z trzema zerami oraz m404_db_version.
- Planowane jest codzienne zadanie cron o nazwie m404_cleanup, pierwsze uruchomienie godzinę po aktywacji. Usuwa ono, partiami po 1000, te wpisy dziennika, które nie zostały trafione w okresie przechowywania. Jeśli zadanie kiedykolwiek zniknie, wtyczka zaplanuje je ponownie przy najbliższym załadowaniu strony.
- Dziennik 404 jest włączony, okres przechowywania to 30 dni, anonimizacja IP jest włączona.
- Automatyczna obsługa 404 jest wyłączona. Domyślny tryb to zwykła strona 404 z motywu, więc wtyczka nie robi z błędem 404 nic poza zapisaniem go.
- Nie ma jeszcze żadnych reguł przekierowania, więc na froncie nie wykonuje się ani jedno zapytanie do bazy.
Gdzie znaleźć ekrany wtyczki
Wtyczka dodaje jedno menu najwyższego poziomu o nazwie 404 Handler, na pozycji 80 w panelu bocznym. Każdy jej ekran wymaga uprawnienia manage_options, więc otworzą je wyłącznie administratorzy. Redaktorzy, autorzy i menedżerowie sklepu w ogóle nie zobaczą tego menu. Interfejs jest po angielsku, więc jeśli nie zainstalujesz tłumaczenia, na polskiej witrynie zobaczysz dokładnie te etykiety.
- 404 Handler, dalej Redirects: lista reguł z przyciskiem Add New. Adres: admin.php?page=m404-redirects
- 404 Handler, dalej 404 Log: zbiorczy zapis martwych linków. Adres: admin.php?page=m404-logs
- 404 Handler, dalej Settings: wszystkie grupy ustawień pod nagłówkiem 404 Handler Settings. Adres: admin.php?page=m404-settings
- Na obu ekranach z listą Opcje ekranu udostępniają Redirects per page oraz Log entries per page. Domyślnie 20, dozwolony zakres od 1 do 500, wartość zapisywana osobno dla każdego użytkownika.
Ekran Redirects i formularz przekierowania
Redirects to główny ekran wtyczki. Przycisk Add New otwiera formularz z pięcioma polami, a szósty wiersz pojawia się wtedy, gdy trafiasz tu z ekranu 404 Log przez Create redirect. Każda utworzona reguła trafia na standardową listę WordPressa z wyszukiwarką, filtrami, sortowaniem kolumn i operacjami masowymi. Celem może być ścieżka względna zaczynająca się od ukośnika albo pełny adres http lub https. Cele bez protokołu w postaci //host są przy zapisie odrzucane, tak samo jak każdy inny schemat, na przykład javascript. Reguła typu Exact, której cel pokrywa się z jej własnym źródłem, w ogóle nie zostanie zapisana. Ta kontrola obejmuje wyłącznie reguły Exact, co ma większe znaczenie, niż się wydaje: zobacz rozdział o operacjach niebezpiecznych.
- Source, pole wymagane. Dla Exact i Prefix jest to ścieżka względna, na przykład /stara-strona/. Dla wyrażenia regularnego wzorzec bez ograniczników, na przykład ^/old-blog/([0-9]+)/(.+)$
- Match type: Exact match (domyślnie), Prefix match albo Regular expression.
- Target, pole wymagane. Ścieżka w rodzaju /nowa-strona/ albo pełny adres, na przykład https://example.com/nowa-strona/.
- Redirect type: 301, 302, 303, 307 lub 308. Formularz otwiera się na 301 i do 301 wtyczka wraca również wtedy, gdy przesłany kod nie jest jednym z tych pięciu.
- Status: pole wyboru Enabled, w nowej regule zaznaczone od razu. Przekierowanie zaczyna działać w chwili zapisu.
- Szósty wiersz, tylko po przejściu z dziennika: pole wyboru proponujące usunięcie tego adresu z dziennika 404 po utworzeniu przekierowania. Jest zaznaczone domyślnie.
- Kolumny listy: Source, Target, Match, Code, Hits, Last hit, Status, Created. Sortować można po Source, Code, Hits, Last hit i Created.
- Filtry nad tabelą: status, kod przekierowania i typ dopasowania, obok pole wyszukiwania obejmujące źródło i cel.
- Operacje masowe: Enable, Disable, Reset hit counters, Delete. Akcje w wierszu: Edit, Enable albo Disable, Reset hits, Delete.
Jak działa dopasowanie i co naprawdę obejmuje
Dopasowanie działa na parse_request z priorytetem 1, jeszcze zanim WordPress zbuduje zapytanie główne. Jest pomijane na ekranach administracyjnych, przy admin-ajax.php, w czasie WP-Cron i pod WP-CLI. Nie jest pomijane przy zapytaniach REST API. Wtyczka sprawdza stałą REST_REQUEST, ale definiuje ją własna funkcja WordPressa podpięta do parse_request z priorytetem 10, więc przy priorytecie 1 ta stała jeszcze nie istnieje. Przez dopasowanie przechodzi zatem wszystko, co WordPress obsługuje przez swój wspólny punkt wejścia: ścieżki /wp-json/, zapytania /?rest_route=, /robots.txt, /wp-sitemap.xml, kanały RSS i adresy wyszukiwania. Jeśli nie masz włączonych reguł danego typu, cały ten typ jest pomijany i nic nie kosztuje.
- Najpierw reguły Exact, znajdowane przez indeks skrótu jednym zapytaniem. Źródło jest potem porównywane jeszcze raz w PHP, więc kolizja skrótu nie uruchomi niewłaściwej reguły.
- Potem reguły Prefix, od najdłuższego źródła. Porównanie to zwykły test znakowy od początku ścieżki. Segmenty adresu nie są brane pod uwagę.
- Jeśli cel reguły prefiksowej kończy się ukośnikiem, reszta adresu zostaje doklejona: źródło /old-blog/ z celem /blog/ zamienia /old-blog/hello na /blog/hello.
- Na końcu wyrażenia regularne, od najstarszej reguły. Wzorzec przechowywany jest bez ograniczników i porównywany ze ścieżką, a $1, $2 i kolejne w celu są zastępowane przechwyconymi grupami. Maksymalna długość wzorca to 500 znaków.
- Wygrywa pierwsza reguła, która da użyteczny cel, i na niej żądanie się kończy.
- Dopasowanie zawsze dotyczy samej ścieżki. Ciągiem zapytania zajmuje się osobne ustawienie Query strings.
- Wzorzec, który zawiedzie w trakcie działania, jest po cichu pomijany. Zepsute wyrażenie regularne nie położy witryny, po prostu nigdy nie pasuje.
- Tylko dopasowanie Exact to jedno indeksowane zapytanie. Reguły Prefix i regularne są przy każdym żądaniu na froncie wczytywane z bazy w całości i porównywane w PHP, więc duży zestaw wyrażeń regularnych kosztuje.
Reguły są sprawdzane, zanim WordPress ustali, czy adres w ogóle istnieje, więc reguła, której źródłem jest działająca strona, ukryje tę stronę przed odwiedzającymi. A ponieważ zapytania REST są dopasowywane tak samo jak wszystkie inne, szeroka reguła po cichu zabiera ze sobą edytor blokowy i Site Health. Jeśli działający adres nagle zaczyna przekierowywać albo edytor przestaje zapisywać, najpierw poszukaj reguły, która to obejmuje, a dopiero potem czegokolwiek innego.
Ustawienia: Redirect matching
Pierwsza sekcja ekranu 404 Handler Settings decyduje o tym, jak przychodzące adresy są porównywane z twoimi regułami. Wszystkie trzy ustawienia są globalne: obejmują od razu każdą regułę. Dwa ostatnie decydują dodatkowo o tym, jak liczony jest klucz wyszukiwania każdej reguły Exact, i właśnie dlatego z tego ekranu w ogóle nie da się ich zmienić. Zanim dotkniesz któregokolwiek z nich, przeczytaj następną sekcję.
- Query strings, z etykietą "Pass the original query string on to the redirect target". Domyślnie włączone. /stara-strona?utm_source=x trafia na /nowa-strona?utm_source=x. Jeśli cel ma już ten sam parametr, wygrywa wartość z celu.
- Case sensitivity, z etykietą "Match URLs case-insensitively". Domyślnie wyłączone. Gdy jest włączone, ścieżki są przed porównaniem zamieniane na małe litery, a każde wyrażenie regularne dostaje dodatkowo flagę i.
- Trailing slashes, z etykietą "Ignore trailing slashes when matching". Domyślnie włączone, więc /kontakt i /kontakt/ liczą się jako ten sam adres. Przy okazji z zapisanych źródeł reguł prefiksowych zdejmowany jest końcowy ukośnik, a czym to się kończy, opisuje rozdział o operacjach niebezpiecznych.
Nie przełączaj na tym ekranie opcji "Match URLs case-insensitively" ani "Ignore trailing slashes when matching". Zapis którejkolwiek z tych zmian kończy się błędem krytycznym PHP na ekranie Settings i niczego nie zapisuje. Następna sekcja podaje jedyną działającą drogę i obowiązkowy drugi krok, który do niej należy.
Dwa ustawienia, których nie da się zapisać z ekranu Settings
Case sensitivity i Trailing slashes to jedyne ustawienia, których zmiana uruchamia przy zapisie dodatkową operację: wtyczka przelicza klucz wyszukiwania każdej reguły Exact. Ta ścieżka nigdy się nie kończy. Funkcja sanityzująca sama wywołuje update_option(), a update_option() ponownie uruchamia dokładnie tę samą funkcję przez filtr sanitize_option_m404_settings, podpięty do niej przez register_setting(). Pamięć podręczna ustawień wtyczki wciąż trzyma starą wartość, więc warunek spełnia się raz za razem, bez końca. Żądanie kończy się błędem krytycznym PHP na stronie options.php.
- Objawem jest biały ekran albo błąd HTTP 500 po naciśnięciu Save Changes na ekranie 404 Handler Settings, i tylko wtedy, gdy naprawdę zmieniłeś jedno z tych dwóch pól wyboru.
- Nic nie ulega uszkodzeniu. Zapis nie dociera do bazy, więc ustawienie zachowuje poprzednią wartość, pozostałe ustawienia na stronie są nietknięte, a front działa dokładnie tak jak wcześniej. Rekurencja mieści się w całości w tym jednym żądaniu do options.php.
- Wszystkie inne ustawienia na tym ekranie zapisują się normalnie, o ile tych dwóch pól wyboru nie ruszasz.
- Droga przez powłokę działa, bo register_setting() uruchamia się wyłącznie na admin_init. Pod WP-CLI rekurencyjny filtr nie zostaje w ogóle podpięty, więc zapis dochodzi do skutku.
- Po zmianie którejkolwiek z tych wartości musisz sam przeliczyć skróty reguł Exact. Nikt inny tego nie zrobi: wtyczka przelicza klucz reguły tylko wtedy, gdy ta reguła jest zapisywana przez panel.
- Reguł Prefix i regularnych to nie dotyczy. Normalizują ścieżkę w momencie dopasowania i nie przechowują żadnego skrótu.
# Change either setting from the shell, never from the Settings screen.
wp option patch update m404_settings case_insensitive 1
wp option patch update m404_settings ignore_trailing_slash 0
# Mandatory second step: recompute the lookup key of every Exact rule.
# Requires the plugin to be active, so the class is loaded.
wp eval '(new M404_Redirect_Repository())->rehash_all();'
# No WP-CLI? Open and re-save every Exact rule under
# 404 Handler > Redirects. Saving a rule recomputes its own key.
Te dwa ustawienia rozstrzygnij, zanim zbudujesz zestaw reguł. Zmienione później bez przeliczenia skrótów sprawiają, że każda reguła Exact wygląda na ekranie Redirects zupełnie normalnie, a nie dopasowuje niczego, i nigdzie nie pojawia się żaden komunikat o przyczynie.
Ustawienia: 404 handling
Ta sekcja decyduje, co dzieje się z odwiedzającym, który trafi na adres nieistniejący i niepasujący do żadnej reguły. Działa na template_redirect z priorytetem 20, już po tym, jak kanoniczne przekierowanie WordPressa i przekierowanie starego slugu miały szansę uratować adres, więc docierają tu tylko prawdziwe błędy 404.
- "When a 404 happens" daje trzy możliwości. Domyślna to "Show the theme's normal 404 page (do nothing)", czyli wtyczka nie robi nic. Druga to "Automatically redirect to a page or URL of your choice". Trzecia to ta, której etykieta zaczyna się od "Show a custom 404 page": wyświetla prawdziwą stronę i zachowuje status 404, a na ekranie do tej etykiety dopisana jest jeszcze uwaga o SEO.
- "Redirect target" łączy listę stron z polem tekstowym. Domyślnie: żadna strona nie jest wybrana, adres pusty. Wybrana strona ma pierwszeństwo przed adresem, przy czym musi być opublikowana, inaczej użyty zostanie adres. Jeśli oba są puste, odwiedzający trafiają na stronę główną. Adres musi być względny i zaczynać się od ukośnika albo być pełnym adresem http lub https; wszystko inne jest przy zapisie odrzucane.
- "Redirect status code" ma domyślnie 302 i dla automatycznego przekierowania 404 jest to właściwa odpowiedź.
- "Custom 404 page" domyślnie nie jest wybrana. Musi to być opublikowana strona, nie wpis. Strona jest wyświetlana z prawdziwym nagłówkiem 404 i nagłówkami zakazu cache, więc wyszukiwarki jej nie zaindeksują. Jeśli wybrana strona zniknie, trafi do kosza albo zostanie szkicem, po cichu przejmuje szablon 404 z motywu.
- Podpowiedzi "Did you mean", domyślnie włączone. Do pięciu opublikowanych wpisów lub stron o slugu podobnym do brakującego. Wtyczka porównuje trzy pierwsze znaki slugu, sprawdza najwyżej 50 kandydatów i zostawia tylko te co najmniej w 40 procentach podobne. Slug krótszy niż trzy znaki nie da nic.
- Podpowiedzi renderują się wyłącznie w trybie „Show a custom 404 page” i zawsze są dopisywane na końcu treści strony. Shortcode [m404_suggestions] ich nie przenosi: dodaje drugą kopię listy w miejscu, w którym go wstawisz. Wtyczka filtruje the_content z priorytetem 20, a WordPress rozwija shortcode’y już przy priorytecie 11, więc sprawdzenie w kodzie wtyczki nigdy shortcode’u nie znajduje. Używaj go tylko wtedy, gdy chcesz mieć listę dwa razy.
- Nagłówki zakazu cache są wysyłane tylko w trybie "Show a custom 404 page". W trybie domyślnym i w trybie automatycznego przekierowania wtyczka nie dodaje żadnych własnych nagłówków cache, cokolwiek mówi plik readme.
[m404_suggestions]
Ustawienia: 404 logging
Dziennik trzyma jeden wiersz na każdy unikalny adres, czyli ścieżkę wraz z ciągiem zapytania, plus licznik trafień, więc bot dobijający się do tego samego brakującego pliku nie zapełni tabeli. Uwaga: wzorce ignorowania wyciszają wyłącznie zapis do dziennika. Ignorowany adres nadal zostanie przekierowany przez tryb automatyczny i nadal dostanie własną stronę 404. Uwaga również na to, że wzorce są porównywane z samą ścieżką, a zapisywany wiersz to ścieżka wraz z ciągiem zapytania.
- Logging, z etykietą "Log 404 errors". Domyślnie włączone.
- Retention. Domyślnie 30 dni, dozwolony zakres od 0 do 3650. Wiersze nietrafione w tym okresie są raz dziennie usuwane partiami po 1000 przez zadanie cron m404_cleanup. Wpisanie 0 oznacza przechowywanie bez końca.
- Privacy, z etykietą "Anonymize visitor IP addresses before storing them". Domyślnie włączone. Odczytywany jest wyłącznie REMOTE_ADDR; nagłówki przekazywane przez proxy są świadomie pomijane, bo można je podrobić.
- Ignore patterns, pole tekstowe po jednym wzorcu na wiersz. Gwiazdka zastępuje dowolny ciąg znaków, wielkość liter nie ma znaczenia. Wzorzec zaczynający się od ukośnika lub gwiazdki jest porównywany z całą ścieżką; wzorzec, który nie zaczyna się od żadnego z nich, dopasowuje koniec ścieżki.
- Domyślna lista ma dwadzieścia wzorców: *.php, *.asp, *.aspx, *.env*, *.git*, *.map, *.axd, /wp-content/*, /wp-includes/*, *.jpg, *.jpeg, *.png, *.gif, *.webp, *.svg, *.ico, *.css, *.js, *.woff*, *.ttf
- Każdy wiersz dziennika przechowuje adres, licznik trafień, ostatni referrer, ostatni user agent, ostatni adres IP oraz daty pierwszego i ostatniego wystąpienia. Adres i referrer są skracane do 2000 znaków, user agent do 255, adres IP do 45.
Pierwsze uruchomienie: co ustawić i w jakiej kolejności
Ustawienia domyślne są już dobrym punktem wyjścia, więc nie konfiguruj wszystkiego pierwszego dnia. Najpierw rozstrzygnij dwa ustawienia normalizacji, bo tylko ich zmiana boli później. Potem wprowadź znane przekierowania, pozwól dziennikowi pokazać, co naprawdę jest zepsute, i dopiero wtedy zdecyduj, co robić z pozostałymi błędami 404.
- Zdecyduj od razu, czy chcesz dopasowania bez rozróżniania wielkości liter i czy końcowe ukośniki mają być ignorowane. Domyślnie jest to odpowiednio wyłączone i włączone. Jeśli chcesz inaczej, ustaw to z powłoki w sposób opisany wcześniej, zanim powstanie choćby jedna reguła.
- Reszty ekranu Settings nie ruszaj. Dziennik jest włączony, okres przechowywania to 30 dni, anonimizacja IP działa, a nic nie jest przekierowywane automatycznie. Pierwszego dnia dokładnie tego potrzebujesz.
- Wprowadź znane przekierowania w Redirects, Add New. Dla pojedynczych adresów użyj Exact match. Każdą regułę utwórz najpierw z kodem 302, sprawdź ją w oknie prywatnym i dopiero potem zmień na 301, jeśli przeniesienie jest trwałe.
- Dla całych przeniesionych sekcji użyj Prefix match. Jeśli reszta adresu ma być przeniesiona, postaw ukośnik na końcu zarówno źródła, jak i celu, a samo źródło nie może być początkiem innego działającego adresu.
- Wyrażenia regularne zostaw na koniec i sięgaj po nie tylko tam, gdzie reguła prefiksowa naprawdę nie wystarcza.
- Po każdej regule prefiksowej lub regularnej wykonaj trzy sprawdzenia: otwórz dowolny wpis w edytorze blokowym i zapisz go, wejdź na /robots.txt, wejdź na /wp-sitemap.xml. Wszystkie trzy muszą zachować się normalnie.
- Pozwól dziennikowi zapełnić się przez tydzień lub dwa. Potem posortuj 404 Log po kolumnie Hits i napraw czołowe pozycje akcją Create redirect, która wypełnia formularz brakującą ścieżką.
- Dodaj wzorce ignorowania dla szumu, który przetrwał listę domyślną, żeby dziennik pozostał czytelny.
- Dopiero teraz wybierz tryb obsługi 404. Bezpieczna opcja to "Show a custom 404 page", bo zachowuje status 404. Automatyczne przekierowanie wybieraj tylko wtedy, gdy godzisz się, że ukryje ono każdy martwy link przed robotami i przed twoimi własnymi raportami.
Operacje niebezpieczne: co może położyć witrynę
Ta wtyczka stoi przed każdym żądaniem na froncie. Właśnie dlatego jest przydatna i właśnie dlatego nieprzemyślana reguła kosztuje. Przeczytaj tę listę, zanim utworzysz pierwszą regułę prefiksową lub z wyrażeniem regularnym i zanim przełączysz obsługę 404 na automatyczne przekierowanie.
- Reguła prefiksowa, której źródłem jest sam ukośnik, dopasuje każdy adres w witrynie i wyśle cały front gdzie indziej. Kontrola samoprzekierowania przy zapisie obejmuje wyłącznie reguły Exact, więc nic cię nie powstrzyma.
- Wyrażenie regularne w rodzaju ^/(.*)$ robi to samo. Wzorce są sprawdzane tylko pod kątem tego, czy się kompilują, nigdy pod kątem tego, jak dużą część witryny obejmują.
- Każda reguła, której źródłem jest istniejący adres, ukrywa ten adres, bo reguły są dopasowywane, zanim WordPress ustali, co istnieje.
- Szeroka reguła łapie także ścieżki /wp-json/. Z kolei reguła, której źródłem jest sam ukośnik, łapie również zapytania /?rest_route=, bo po normalizacji ich ścieżka to właśnie ten jeden ukośnik. Sam wp-admin wygląda zupełnie normalnie, ale edytor blokowy nie wczyta ani nie zapisze wpisu, a Site Health przestaje działać. Komunikaty błędów nie mówią ani słowa o przekierowaniach.
- Szeroka reguła łapie także /robots.txt, /wp-sitemap.xml i kanały RSS. Przekierowanie ich po cichu wyrzuca witrynę z indeksu, a w odróżnieniu od zepsutej strony nikt nie zauważa tego przez tygodnie.
- Dopasowanie prefiksowe to zwykłe porównanie znaków, a przy włączonym "Ignore trailing slashes" zapisane źródło /old-blog/ normalizuje się do /old-blog. Ta sama reguła łapie więc również /old-blogger i /old-blog-archive, a z celem zakończonym ukośnikiem zamienia /old-blogging na /blog/ging. Działające strony znikają, a cel wychodzi bezsensowny.
- Pętle przekierowań. Zabezpieczenie działające w czasie żądania odrzuca tylko taki cel, którego znormalizowana ścieżka równa się bieżącej, więc łańcucha nie wyłapie. Reguła prefiksowa ze źródłem /shop i celem /shop/new/ dopasowuje własny wynik i bez końca produkuje /shop/new/new/new/. To samo robi wyrażenie regularne bez zakotwiczenia: wzorzec blog z celem blog-new zamienia /blog na /blog-new, do którego ten sam wzorzec nadal pasuje. Dwie reguły wskazujące na siebie nawzajem dają odwiedzającemu ERR_TOO_MANY_REDIRECTS.
- Żadnego przekierowania 301 nie da się odwołać, gdy raz trafi do cache. Dotyczy to reguły przekierowania zapisanej z kodem 301 dokładnie tak samo jak automatycznego trybu 404 ustawionego na 301. Przeglądarki, proxy i CDN-y trzymają się go długo po tym, jak naprawisz regułę. Formularz reguły otwiera się właśnie na 301, więc to najłatwiejszy błąd do popełnienia.
- Samo wybranie automatycznego przekierowania sprawia, że każdy martwy link staje się niewidoczny dla robotów, bo zamiast 404 widzą działającą stronę. Dziennik nadal je zapisuje, twoje narzędzia SEO już nie.
- Włączenie reguły prefiksowej lub regularnej, której cel wskazuje na zewnętrzny host, dopisuje ten host do listy dozwolonych hostów przekierowań WordPressa dla całej witryny, na cały czas działania reguły. Od tej chwili każde wywołanie wp_safe_redirect w dowolnym miejscu witryny ten host zaakceptuje. Reguły Exact tego nie robią.
Każdą nową regułę buduj z kodem 302, sprawdź ją w oknie prywatnym i dopiero potem przełącz na 301. Zbyt szeroka reguła prefiksowa lub regularna odcina realnych odwiedzających od całej witryny i przy okazji psuje edytor blokowy. Pętla 301, która już zdążyła wyjść na produkcję, znika po stronie serwera w chwili wyłączenia reguły, ale odwiedzający, którzy już w nią trafili, pozostają uwięzieni do czasu wyczyszczenia cache przeglądarki.
Odzyskiwanie awaryjne: wszystko przekierowuje albo edytor przestał zapisywać
Uczciwa wersja tej obietnicy jest węższa niż "nie zamkniesz sobie drogi do panelu". Wczytanie strony w wp-admin ani w wp-login.php nie uruchamia dopasowania, bo żadne z nich nie wywołuje wp(), więc zawsze zalogujesz się, otworzysz ekrany wtyczki i cofniesz to, co robi reguła. Szeroka reguła sięga czego innego: wszystkiego, co wp-admin robi przez REST API, czyli edytora blokowego, Site Health i aplikacji mobilnej. Ten rozdział opisuje więc dwa różne objawy, a jeden z nich w ogóle nie wygląda na problem z przekierowaniami.
- Zaloguj się pod /wp-login.php i otwórz 404 Handler, dalej Redirects. Żadna reguła na tę stronę nie wpływa.
- Przefiltruj listę po typie dopasowania Prefix match, potem Regular expression. Przekierowanie obejmujące całą witrynę będzie prawie zawsze jednym z tych dwóch, tak samo jak zepsuty edytor.
- Na podejrzanej regule użyj akcji Disable, a nie Delete, żeby móc ją potem obejrzeć. Wyłączenie działa natychmiast.
- Otwórz dowolny wpis w edytorze blokowym i zapisz go. Jeśli edytor skarżył się na nieprawidłową odpowiedź JSON albo na nieudaną publikację, a teraz zapisuje, to właśnie ta reguła łapała /wp-json/.
- Wejdź bezpośrednio na /robots.txt i /wp-sitemap.xml i sprawdź, czy zwracają własną treść, a nie przekierowanie.
- Jeśli front dalej zachowuje się źle, otwórz Settings i przywróć "When a 404 happens" na "Show the theme's normal 404 page (do nothing)".
- Jeśli z zupełnie innego powodu nie da się dostać nawet do wp-admin, uruchom przez SSH jedną z poniższych komend albo przez SFTP zmień nazwę folderu wtyczki zawierającego m-404-handler.php. Zmiana nazwy folderu dezaktywuje wtyczkę i zostawia wszystkie reguły, cały dziennik i wszystkie ustawienia nietknięte.
# Deactivate the plugin completely; all rules and logs are kept.
wp plugin deactivate m-404-handler
# On a multisite network, add --network.
# Or keep it active and make every rule stop matching. Temporary only.
wp option update m404_rule_counts '{"exact":0,"prefix":0,"regex":0}' --format=json
# Or turn off only the automatic 404 redirect.
wp option patch update m404_settings fallback_mode none
# Or disable one rule directly in SQL (use your own table prefix).
# Disabling in SQL takes effect at once.
wp db query "UPDATE wp_m404_redirects SET enabled = 0 WHERE id = 12;"
# But RE-ENABLING in SQL does nothing while the cached counts say the
# type has no rules. Refresh them, or the rule stays dead:
wp eval '(new M404_Redirect_Repository())->refresh_counts();'
Sztuczka z m404_rule_counts jest tylko tymczasowa. Wtyczka przelicza tę opcję w chwili, gdy jakakolwiek reguła zostanie zapisana, włączona, wyłączona lub usunięta, więc wszystkie reguły wrócą do życia. Działa to też w drugą stronę: dopóki licznik danego typu wynosi zero, żadna reguła tego typu nie może zadziałać, cokolwiek stoi w kolumnie enabled, więc po każdej bezpośredniej zmianie w SQL trzeba liczniki odświeżyć. Napraw właściwą regułę, zanim znów dotkniesz ekranu Redirects.
Usuwanie, którego nie da się cofnąć
W tej wtyczce nie ma kosza, cofania ani eksportu. Wszystko poniżej usuwa dane natychmiast i na stałe, a część z tego usuwa znacznie więcej, niż sugeruje nazwa przycisku.
- "Delete all log entries" na ekranie 404 Log opróżnia całą tabelę dziennika jednym poleceniem. Jedynym zabezpieczeniem jest okienko potwierdzenia w przeglądarce.
- Tym poleceniem jest TRUNCATE TABLE, które wymaga uprawnienia DROP. Część hostingów zarządzanych nie przyznaje go użytkownikowi bazy danych witryny. Wtyczka nie sprawdza wyniku i tak czy inaczej wypisuje "The 404 log has been emptied.", więc zanim na tym polegniesz, przeładuj ekran 404 Log i upewnij się, że naprawdę jest pusty.
- Delete na pojedynczych wierszach dziennika oraz masowe Delete na tym samym ekranie. Żadne z nich nie prosi o potwierdzenie.
- Delete na ekranie Redirects. Akcja w wierszu prosi o potwierdzenie, operacja masowa już nie, więc omyłkowo zaznaczone pole może dwoma kliknięciami skasować całą stronę reguł.
- Oba ekrany z listą są renderowane w formularzu GET, więc operacje masowe wędrują w ciągu zapytania. Masowe Delete całej strony reguł ląduje wraz ze swoim tokenem jednorazowym w historii przeglądarki, w logu dostępowym serwera i w każdym logu proxy po drodze, a przez cały okres ważności tego tokenu daje się odtworzyć.
- "Reset hit counters" zeruje licznik trafień i czyści datę ostatniego trafienia dla wybranych reguł. Dokładnie tak traci się dowody na to, które przekierowania są jeszcze potrzebne. To jedyna operacja masowa, która nie odświeża zapisanych liczników reguł, bo nie musi.
- Obniżenie wartości Retention. Przy najbliższym dobowym uruchomieniu m404_cleanup usuwany jest każdy wiersz dziennika nietrafiony w nowym okresie. Zmiana z 365 dni na 7 wyrzuca roczne dane w ciągu doby, bez żadnego ostrzeżenia w momencie zapisu.
- Pole wyboru "Remove this URL from the 404 log after creating the redirect" w formularzu przekierowania, zaznaczone domyślnie zawsze, gdy trafiasz tam z dziennika.
Jeśli lista reguł albo dziennik 404 ma dla ciebie znaczenie, przed każdą operacją masową zrób kopię bazy danych. Po zmianie obu tabel we wtyczce nie ma niczego, co przywróciłoby dane.
Gdy coś nie działa
Krótka lista tego, co naprawdę psuje się w praktyce, i tego, co w każdym przypadku sprawdzić najpierw.
- Przekierowanie nic nie robi. Sprawdź, czy reguła ma status Enabled, a potem czy wcześniejsza reguła już nie zadziałała: najpierw reguły Exact, potem najdłuższy prefiks, na końcu wyrażenia regularne w kolejności utworzenia.
- Edytor blokowy nie zapisuje albo Site Health przestaje działać, a zaczęło się to zaraz po dodaniu reguły. Reguła prefiksowa lub regularna łapie /wp-json/. Wyłącz ją i sprawdź ponownie.
- Wszystkie reguły Exact przestały działać naraz i nic na ekranie tego nie tłumaczy. Ktoś zmienił Case sensitivity albo Trailing slashes bez przeliczenia skrótów. Uruchom polecenie przeliczające albo zapisz ponownie każdą regułę Exact.
- Jedna reguła działa, druga po cichu nie, a ponowny zapis dowolnej reguły naprawia sprawę. Wtyczka trzyma w opcji m404_rule_counts liczbę włączonych reguł według typu, a gdy ta liczba wynosi zero, cały typ zostaje pominięty. Otwórz dowolną regułę i zapisz ją, żeby wymusić przeliczenie.
- Włączyłeś regułę bezpośrednio w SQL i nic się nie stało. Zapisane liczniki nie zostały odświeżone. Zapisz dowolną regułę przez panel albo odśwież liczniki z powłoki.
- Dziennik 404 pozostaje pusty. Albo zapis jest wyłączony, albo adresy łapią wzorce ignorowania (lista domyślna wyklucza już .php, obrazy, CSS, JS, fonty i wszystko pod /wp-content/ i /wp-includes/), albo cache pełnych stron lub CDN podaje 404 tak, że WordPress w ogóle się nie uruchamia. Jeśli twój CDN buforuje wszystko, wyklucz odpowiedzi 404.
- Stare wpisy dziennika nigdy nie znikają. Okres przechowywania realizuje wyłącznie codzienne zadanie cron m404_cleanup. Jeśli WP-Cron jest wyłączony i nie zastępuje go cron systemowy, nic nie jest czyszczone. Istnienie zadania potwierdzisz poleceniem wp cron event list.
- Zamiast własnej strony 404 pokazuje się 404 z motywu. Wybrana strona musi istnieć, być typu page i być opublikowana. Szkic albo strona w koszu powodują ciche wycofanie.
- Podpowiedzi nigdy się nie pojawiają. Renderują się tylko w trybie "Show a custom 404 page", potrzebują brakującego slugu o długości co najmniej trzech znaków i opublikowanego wpisu lub strony o slugu podobnym w co najmniej 40 procentach.
- Wyrażenie regularne zapisuje się, ale nigdy nie działa. Wzorzec jest przechowywany bez ograniczników i porównywany wyłącznie ze ścieżką, więc potrzebuje w sobie początkowego ukośnika, na przykład ^/old-blog/.
- Kolega nie widzi menu. Wszystkie trzy ekrany wymagają uprawnienia manage_options, więc widzą je tylko administratorzy.
- Komunikat błędu 404 Handler pojawia się na stronie wp-admin, na której się go nie spodziewałeś. Wtyczka wypisuje na dowolnym ekranie administracyjnym dokładnie ten tekst, który stoi w parametrze zapytania m404_error, bez tokenu jednorazowego i bez sprawdzania adresu odsyłającego. Tekst jest zabezpieczany przed wykonaniem kodu, ale każdy, kto skłoni cię do kliknięcia spreparowanego linku, umieści własne słowa w komunikacie wyglądającym na prawdziwy komunikat WordPressa. Komunikatowi, który przyszedł z linku, nie ufaj i nigdy nie korzystaj z podanego w nim numeru telefonu ani adresu.
Prywatność i dane
Wtyczka nie nawiązuje żadnych połączeń na zewnątrz. Nie ma tu odsyłania danych do autora, sprawdzania aktualizacji poza witryną, analityki ani weryfikacji licencji. Nie ma też kodu wysyłającego wiadomości e-mail, więc w żaden sposób nie może zakłócić wysyłki poczty z witryny. Wszystko, co wtyczka wie, zostaje w twojej własnej bazie danych.
- W tabeli wp_m404_redirects: źródło, typ dopasowania, cel, kod statusu, znacznik włączenia, licznik trafień, czas ostatniego trafienia oraz daty utworzenia i aktualizacji. Żadnych danych odwiedzających.
- W tabeli wp_m404_404_log: brakujący adres wraz z ciągiem zapytania, licznik trafień, ostatni referrer, ostatni user agent, ostatni adres IP oraz daty pierwszego i ostatniego wystąpienia.
- Gdy opcja "Anonymize visitor IP addresses" jest włączona, czyli domyślnie, adresy IP przechodzą przez własną funkcję anonimizującą WordPressa. Odczytywany jest wyłącznie REMOTE_ADDR, nigdy nagłówek proxy.
- Włączenie anonimizacji później nie porządkuje tego, co już zapisano. Funkcja działa wyłącznie w momencie zapisu, więc istniejące wiersze zachowują pełne adresy IP do czasu, aż ten sam adres zostanie trafiony ponownie albo wiersz usunie okres przechowywania. Wyczyść dziennik albo odczekaj okres przechowywania, a do tego czasu traktuj stare wiersze jak dane osobowe.
- Jeśli wolisz nie przechowywać o odwiedzających niczego, wyłącz Logging. Przekierowania działają dalej dokładnie tak samo.
- Do dziennika trafiają tylko adresy, które wywołały prawdziwy błąd 404 i nie pasują do żadnego z twoich wzorców ignorowania.
- Po wyłączeniu anonimizacji w dzienniku zostaje pełny adres IP i user agent, czyli dane osobowe. Napisz o tym w polityce prywatności i trzymaj krótki okres przechowywania.
- Masowo usuwane wiersze dziennika wędrują żądaniem GET, więc adresy zaznaczonych wierszy trafiają do historii przeglądarki i do logu dostępowego serwera. Warto o tym wiedzieć, jeśli same zapisane adresy są wrażliwe.
Odinstalowanie: co znika, a co zostaje
Dezaktywacja i usunięcie robią tu zupełnie różne rzeczy, a różnicą jest cała historia twoich przekierowań. Dezaktywuj, gdy chcesz, żeby wtyczka przestała działać. Usuwaj dopiero wtedy, gdy masz pewność, że reguły nie będą już potrzebne.
- Dezaktywacja zatrzymuje całe dopasowywanie i usuwa z harmonogramu codzienne zadanie m404_cleanup na bieżącej witrynie. Obie tabele, wszystkie reguły, cały dziennik i wszystkie ustawienia zostają bez zmian, a ponowna aktywacja podejmuje pracę w tym samym miejscu.
- W sieci multisite hak dezaktywacji czyści zadanie cron tylko na tej jednej witrynie, na której się uruchomił. Każda inna witryna w sieci zachowuje zaplanowane m404_cleanup, które potem odpala się codziennie bez podpiętej funkcji. Nie wyrządza to szkody, ale i porządku nie wprowadza, więc jeśli ci na tym zależy, usuń je na każdej witrynie poleceniem wp cron event delete m404_cleanup.
- Usunięcie wtyczki z ekranu Wtyczki uruchamia deinstalator, który kasuje tabele wp_m404_redirects i wp_m404_404_log, usuwa opcje m404_settings, m404_rule_counts oraz m404_db_version i czyści zadanie cron. W sieci multisite robi to na każdej witrynie w sieci.
- Ta pętla multisite wykonuje się w jednym żądaniu i nie ogranicza liczby witryn. W dużej sieci żądanie może przerwać się w połowie: na witrynach już przetworzonych tabele są skasowane, na pozostałych nietknięte, a wznowić się tego nie da inaczej niż przez ponowną instalację i ponowne usunięcie. Sprawdź potem, czy nigdzie nie zostały tabele m404_.
- Co przetrwa usunięcie: wartości opcji ekranu przypisane do użytkownika, m404_redirects_per_page i m404_logs_per_page, zostają w tabeli metadanych użytkowników.
- Poza bazą danych nic nie jest zapisywane. W katalogu wp-content nie powstają żadne pliki. Shortcode [m404_suggestions] przestaje jednak być zarejestrowany, a WordPress nie usuwa z treści shortcode'u, którego już nie zna: na stronie pojawia się wtedy dosłowny tekst [m404_suggestions]. Usuń go ze strony, zanim dezaktywujesz albo usuniesz wtyczkę.
Usunięcie wtyczki niszczy wszystkie utworzone kiedykolwiek reguły przekierowań oraz cały dziennik 404. Jeśli istnieje choć cień szansy, że zainstalujesz ją ponownie, zamiast tego dezaktywuj albo najpierw zrób zrzut obu tabel. W sieci multisite zrób ten zrzut niezależnie od wszystkiego, bo przerwane odinstalowanie zostawia sieć wyczyszczoną tylko w połowie.
Automatyczne aktualizacje
Wtyczka sprawdza majevski.com pod kątem nowych wydań i proponuje je przez zwykły ekran aktualizacji WordPressa — ten sam komunikat, lista zmian i instalacja jednym kliknięciem jak przy każdej innej wtyczce. Sprawdzenia są buforowane, nigdy nie spowalniają strony i są odporne na awarie: jeśli majevski.com jest nieosiągalny, witryna po prostu działa dalej i próbuje później. Pakiet aktualizacji jest przyjmowany wyłącznie z majevski.com przez HTTPS, a starsza wersja nigdy nie jest proponowana. Wersje starsze niż 1.1.0 nie znają jeszcze kanału aktualizacji, więc nie widzą nowych wydań — zainstaluj raz ręcznie 1.1.0 lub nowszą, a każde kolejne wydanie przyjdzie samo.
Potrzebujesz czegoś podobnego?
Wszystko na tej stronie zaprojektowała, zbudowała i utrzymuje jedna osoba. Jeśli potrzebujesz tego samego dla swojej firmy, napisz, co masz na myśli.
Umów rozmowę otwiera się w nowej karcie