Renderowanie danych zewnętrznych API w blokach WordPress na zapleczu PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Renderowanie zewnętrznych danych API w blokach WordPress na zapleczu

To jest kontynuacja mojego ostatniego artykułu o „Renderowanie zewnętrznych danych API w blokach WordPress na interfejsie”. W tym ostatnim nauczyliśmy się, jak wziąć zewnętrzny interfejs API i zintegrować go z blokiem, który renderuje pobrane dane na interfejsie witryny WordPress.

Chodzi o to, że osiągnęliśmy to w sposób, który uniemożliwia nam zobaczenie danych w edytorze bloków WordPress. Innymi słowy, możemy wstawić blok na stronie, ale nie otrzymujemy jego podglądu. Widzimy blok tylko wtedy, gdy jest opublikowany.

Wróćmy do przykładowej wtyczki bloku, którą stworzyliśmy w poprzednim artykule. Tylko tym razem użyjemy ekosystemu JavaScript i React WordPressa, aby pobrać i wyrenderować te dane również w edytorze bloków zaplecza.

Gdzie skończyliśmy

Kiedy to zaczynamy, oto demo gdzie wylądowaliśmy w ostatnim artykule, do którego możesz się odwołać. Być może zauważyłeś, że użyłem render_callback w poprzednim artykule, abym mógł skorzystać z atrybutów w pliku PHP i renderować zawartość.

Cóż, może to być przydatne w sytuacjach, w których będziesz musiał użyć natywnej funkcji WordPress lub PHP do tworzenia bloków dynamicznych. Ale jeśli chcesz skorzystać tylko z ekosystemu JavaScript i React (w szczególności JSX) WordPressa do renderowania statycznego kodu HTML wraz z atrybutami przechowywanymi w bazie danych, musisz tylko skupić się na Edit i Save funkcje wtyczki bloku.

  • Połączenia Edit Funkcja renderuje zawartość na podstawie tego, co chcesz zobaczyć w Edytorze bloku. Tutaj możesz mieć interaktywne komponenty React.
  • Połączenia Save funkcja renderuje zawartość na podstawie tego, co chcesz zobaczyć na interfejsie. Nie możesz mieć tutaj zwykłych komponentów Reacta ani haków. Służy do zwracania statycznego kodu HTML zapisanego w bazie danych wraz z atrybutami.

Połączenia Save funkcja to miejsce, w którym dzisiaj spędzamy czas. Możemy tworzyć interaktywne komponenty na interfejsie użytkownika, ale w tym celu musimy ręcznie dołączyć i uzyskać do nich dostęp poza Save funkcji w pliku, tak jak to zrobiliśmy w poprzednim artykule.

Zamierzam więc omówić ten sam temat, co w poprzednim artykule, ale tym razem możesz zobaczyć podgląd w Edytorze bloku zanim publikujesz go w interfejsie użytkownika.

Rekwizyty blokowe

Celowo pominąłem wszelkie wyjaśnienia dotyczące edit właściwości funkcji w poprzednim artykule, ponieważ odciągnęłoby to uwagę od głównego punktu, czyli renderowania.

Jeśli pochodzisz ze środowiska React, prawdopodobnie zrozumiesz, o czym mówię, ale jeśli jesteś w tym nowy, polecam sprawdzanie komponentów i rekwizytów w dokumentacji React.

Jeśli zarejestrujemy props obiektu do konsoli, zwraca listę funkcji WordPressa i zmiennych związanych z naszym blokiem:

Renderowanie zewnętrznych danych API w blokach WordPress na zapleczu

Potrzebujemy tylko attributes obiekt i setAttributes funkcji, którą zamierzam zdestrukturyzować z props obiekt w moim kodzie. W ostatnim artykule zmodyfikowałem kod RapidAPI, abym mógł przechowywać dane API poprzez setAttributes(). Rekwizyty są tylko czytelne, więc nie możemy ich bezpośrednio modyfikować.

Rekwizyty blokowe są podobne do zmiennych stanu i setState w React, ale React działa po stronie klienta i setAttributes() służy do trwałego przechowywania atrybutów w bazie danych WordPressa po zapisaniu posta. Więc to, co musimy zrobić, to zapisać je, aby attributes.data a następnie nazwij to jako wartość początkową dla useState() zmienna.

Połączenia edit funkcjonować

Skopiuję i wkleję kod HTML, którego użyliśmy w football-rankings.php w ostatnim artykule i edytuj go trochę, aby przejść do tła JavaScript. Pamiętasz, jak w poprzednim artykule stworzyliśmy dwa dodatkowe pliki do stylizacji i skryptów frontendu? Przy obecnym sposobie podejścia do rzeczy nie ma potrzeby tworzenia tych plików. Zamiast tego możemy przenieść to wszystko do Edit funkcja.

Pełny kod
import { useState } from "@wordpress/element";
export default function Edit(props) {
  const { attributes, setAttributes } = props;
  const [apiData, setApiData] = useState(null);
    function fetchData() {
      const options = {
        method: "GET",
        headers: {
          "X-RapidAPI-Key": "Your Rapid API key",
          "X-RapidAPI-Host": "api-football-v1.p.rapidapi.com",
        },
      };
      fetch(
        "https://api-football-v1.p.rapidapi.com/v3/standings?season=2021&league=39",
          options
      )
      .then((response) => response.json())
      .then((response) => {
        let newData = { ...response }; // Deep clone the response data
        setAttributes({ data: newData }); // Store the data in WordPress attributes
        setApiData(newData); // Modify the state with the new data
      })
      .catch((err) => console.error(err));
    }
    return (
      
{apiData && (
Rank
Logo
Team name
GP
GW
GD
GL
GF
GA
Pts
Form history
{/* Usage of [0] might be weird but that is how the API structure is. */} {apiData.response[0].league.standings[0].map((el) => { {/* Destructure the required data from all */} const { played, win, draw, lose, goals } = el.all; return (
{el.rank}
Rendering External API Data in WordPress Blocks on the Back End PlatoBlockchain Data Intelligence. Vertical Search. Ai.
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => { return (
{result}
); })}
); } )}
)}
); }

Dołączyłem hak React useState() od @wordpress/element zamiast używać go z biblioteki React. Dzieje się tak dlatego, że gdybym miał załadować zwykły sposób, pobrałby React dla każdego bloku, którego używam. Ale jeśli używam @wordpress/element ładuje się z jednego źródła, tj. warstwy WordPress na wierzchu React.

Tym razem też nie zapakowałem kodu do środka useEffect() ale wewnątrz funkcji, która jest wywoływana tylko po kliknięciu przycisku, dzięki czemu mamy podgląd na żywo pobranych danych. Użyłem zmiennej stanu o nazwie apiData do warunkowego renderowania tabeli ligowej. Tak więc po kliknięciu przycisku i pobraniu danych ustawiam apiData do nowych danych wewnątrz fetchData() i dostępny jest render z kodem HTML tabeli rankingów piłkarskich.

Zauważysz, że po zapisaniu wpisu i odświeżeniu strony, tabela ligowa zniknie. Dzieje się tak, ponieważ używamy pustego stanu (null) Dla apiDatawartość początkowa. Po zapisaniu wpisu atrybuty są zapisywane w attributes.data obiekt i nazywamy go jako wartość początkową dla useState() zmienna w ten sposób:

const [apiData, setApiData] = useState(attributes.data);

Połączenia save funkcjonować

Zrobimy prawie to samo z save funkcji, ale trochę ją zmodyfikuj. Na przykład nie ma potrzeby używania przycisku „Pobierz dane” w interfejsie, a apiData zmienna state jest również niepotrzebna, ponieważ sprawdzamy ją już w edit funkcjonować. Ale potrzebujemy losowego apiData zmienna, która sprawdza attributes.data do warunkowego renderowania JSX, w przeciwnym razie wygeneruje niezdefiniowane błędy, a interfejs Edytora bloków będzie pusty.

Pełny kod
export default function save(props) {
  const { attributes, setAttributes } = props;
  let apiData = attributes.data;
  return (
    
      {/* Only render if apiData is available */}
      {apiData && (
        
Rank
Logo
Team name
GP
GW
GD
GL
GF
GA
Pts
Form history
{/* Usage of [0] might be weird but that is how the API structure is. */} {apiData.response[0].league.standings[0].map((el) => { const { played, win, draw, lose, goals } = el.all; return (
{el.rank}
Rendering External API Data in WordPress Blocks on the Back End PlatoBlockchain Data Intelligence. Vertical Search. Ai.
{el.team.name}
{played}
{win}
{draw}
{lose}
{goals.for}
{goals.against}
{el.points}
{el.form.split("").map((result) => { return (
{result}
); })}
); })}
)} ); }

Jeśli modyfikujesz save funkcja po tym, jak blok jest już obecny w Edytorze bloku, wyświetli błąd taki:

Blok rankingów piłkarskich w edytorze bloków WordPress z komunikatem o błędzie, że blok zawiera nieoczekiwany błąd.
Renderowanie zewnętrznych danych API w blokach WordPress na zapleczu

Dzieje się tak, ponieważ znaczniki w zapisanej treści różnią się od znaczników w naszym nowym save funkcjonować. Ponieważ jesteśmy w trybie programistycznym, łatwiej jest usunąć blokadę z bieżącej strony i wstawić ją ponownie jako nowy blok — w ten sposób zamiast tego zostanie użyty zaktualizowany kod i wszystko będzie zsynchronizowane.

Tej sytuacji usunięcia go i ponownego dodania można uniknąć, gdybyśmy użyli render_callback metoda, ponieważ wyjście jest dynamiczne i kontrolowane przez PHP zamiast funkcji save. Tak więc każda metoda ma swoje zalety i wady.

Tom Nowell dokładnie wyjaśnia, czego nie robić w save funkcja w ten przepełnienie stosu odpowiedź.

Stylizowanie bloku w edytorze i interfejsie

Jeśli chodzi o stylizację, będzie to prawie to samo, o czym mówiliśmy w poprzednim artykule, ale z drobnymi zmianami, które wyjaśniłem w komentarzach. Po prostu dostarczam tutaj pełne style, ponieważ jest to tylko dowód koncepcji, a nie coś, co chcesz skopiować-wkleić (chyba że naprawdę potrzebujesz bloku do wyświetlania rankingów piłkarskich w takim stylu). I zauważ, że nadal używam SCSS, który kompiluje do CSS przy kompilacji.

Style edytora
/* Target all the blocks with the data-title="Football Rankings" */
.block-editor-block-list__layout 
.block-editor-block-list__block.wp-block[data-title="Football Rankings"] {
  /* By default, the blocks are constrained within 650px max-width plus other design specific code */
  max-width: unset;
  background: linear-gradient(to right, #8f94fb, #4e54c8);
  display: grid;
  place-items: center;
  padding: 60px 0;

  /* Button CSS - From: https://getcssscan.com/css-buttons-examples - Some properties really not needed :) */
  button.fetch-data {
    align-items: center;
    background-color: #ffffff;
    border: 1px solid rgb(0 0 0 / 0.1);
    border-radius: 0.25rem;
    box-shadow: rgb(0 0 0 / 0.02) 0 1px 3px 0;
    box-sizing: border-box;
    color: rgb(0 0 0 / 0.85);
    cursor: pointer;
    display: inline-flex;
    font-family: system-ui, -apple-system, system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 16px;
    font-weight: 600;
    justify-content: center;
    line-height: 1.25;
    margin: 0;
    min-height: 3rem;
    padding: calc(0.875rem - 1px) calc(1.5rem - 1px);
    position: relative;
    text-decoration: none;
    transition: all 250ms;
    user-select: none;
    -webkit-user-select: none;
    touch-action: manipulation;
    vertical-align: baseline;
    width: auto;
    &:hover,
    &:focus {
      border-color: rgb(0, 0, 0, 0.15);
      box-shadow: rgb(0 0 0 / 0.1) 0 4px 12px;
      color: rgb(0, 0, 0, 0.65);
    }
    &:hover {
      transform: translateY(-1px);
    }
    &:active {
      background-color: #f0f0f1;
      border-color: rgb(0 0 0 / 0.15);
      box-shadow: rgb(0 0 0 / 0.06) 0 2px 4px;
      color: rgb(0 0 0 / 0.65);
      transform: translateY(0);
    }
  }
}
Style front-endowe
/* Front-end block styles */
.wp-block-post-content .wp-block-football-rankings-league-table {
  background: linear-gradient(to right, #8f94fb, #4e54c8);
  max-width: unset;
  display: grid;
  place-items: center;
}

#league-standings {
  width: 900px;
  margin: 60px 0;
  max-width: unset;
  font-size: 16px;
  .header {
    display: grid;
    gap: 1em;
    padding: 10px;
    grid-template-columns: 1fr 1fr 3fr 4fr 3fr;
    align-items: center;
    color: white;
    font-size: 16px;
    font-weight: 600;
    background-color: transparent;
    background-repeat: no-repeat;
    background-size: contain;
    background-position: right;

    .stats {
      display: flex;
      gap: 15px;
      & > div {
        width: 30px;
      }
    }
  }
}
.league-table {
  background: white;
  box-shadow:
    rgba(50, 50, 93, 0.25) 0px 2px 5px -1px,
    rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
  padding: 1em;
  .position {
    width: 20px;
  }
  .team {
    display: grid;
    gap: 1em;
    padding: 10px 0;
    grid-template-columns: 1fr 1fr 3fr 4fr 3fr;
    align-items: center;
  }
  .team:not(:last-child) {
    border-bottom: 1px solid lightgray;
  }
  .team-logo img {
    width: 30px;
    top: 3px;
    position: relative;
  }
  .stats {
    display: flex;
    gap: 15px;
    & > div {
      width: 30px;
      text-align: center;
    }
  }
  .last-5-games {
    display: flex;
    gap: 5px;
    & > div {
      width: 25px;
      height: 25px;
      text-align: center;
      border-radius: 3px;
      font-size: 15px;
    & .result-W {
      background: #347d39;
      color: white;
    }
    & .result-D {
      background: gray;
      color: white;
    }
    & .result-L {
      background: lightcoral;
      color: white;
    }
  }
}

Dodajemy to do src/style.scss który dba o stylizację zarówno w edytorze, jak i we frontendzie. Nie będę mógł udostępnić adresu URL demonstracji, ponieważ wymagałoby to dostępu redaktora, ale mam nagrane wideo, aby zobaczyć demo:


Całkiem schludny, prawda? Teraz mamy w pełni funkcjonalny blok, który nie tylko renderuje w interfejsie użytkownika, ale także pobiera dane API i renderuje bezpośrednio w Edytorze bloku — z przyciskiem odświeżania do uruchomienia!

Ale jeśli chcemy wziąć pełny zaletą edytora bloków WordPress, powinniśmy rozważyć zmapowanie niektórych elementów interfejsu użytkownika bloku do kontrolki blokowe do takich rzeczy jak ustawianie koloru, typografii i odstępów. To miły kolejny krok na drodze uczenia się programowania blokowego.

Znak czasu:

Więcej z Sztuczki CSS