#wordpress #vue.js #api

Vue.js jako wtyczka do WordPressa

Avatar of Mikołaj GrendziszMikołaj Grendzisz

vue.js jako wtyczka do WordPressa

Vue.js to biblioteka JavaScript, która umożliwia software developerom tworzyć proste aplikacje. Nie jest to jedyne tego typu narzędzie na rynku, jednak to właśnie Vue.js z każdym rokiem zyskuje coraz większą popularność. Wszystko to za sprawą szybkości pisania kodu, prostej składni oraz skalowalności aplikacji. Warto zatem przyjrzeć się możliwościom zastosowania tego frameworku. Jedno z nich opisałem dla Ciebie w tym poradniku. Vue.js jako wtyczka do WordPressa to łatwe do wdrożenia rozwiązanie, które bez problemu możesz zastosować w kolejnych projektach. Mam nadzieję, że artykuł zachęci Cię do dalszego zgłębiania tej tematyki.

Vue.js zawiera stopniowo adaptowalną architekturę, która koncentruje się na renderowaniu deklaratywnym i tworzeniu komponentów. Ideą stojącą za Vue.js jest ponowne wykorzystanie przygotowanych wcześniej komponentów. Podstawowa biblioteka koncentruje się tylko na warstwie widoku. Zaawansowane funkcje wymagane w przypadku złożonych aplikacji (takich jak routing, zarządzanie stanem i narzędzia do budowania) są oferowane za pośrednictwem oficjalnie utrzymywanych bibliotek pomocniczych, np. BootstrapVue.

Vue.js pozwala na rozszerzenie HTML o atrybuty HTML zwane dyrektywami. Dyrektywy oferują dodatkową funkcjonalność dla HTML i są dostępne jako dyrektywy wbudowane lub zdefiniowane przez użytkownika.

Dlaczego warto wybrać Vue.js jako wtyczkę do WordPressa?

Vue.js to świetne rozwiązanie dla WordPressa głównie za sprawą łatwości integracji i możliwości prostej adaptacji z dowolnym API, a dzięki wyborze takiej konfiguracji masz możliwość rozbudowy strony o dodatkową funkcjonalność.

Do kogo kierowany jest ten poradnik?

Poradnik kierowany jest do osób, które chciałyby rozwinąć możliwości WordPressa przy pomocy frameworku Vue.js oraz posiadają podstawowe doświadczenie w pracy z frameworkami Javascript: Vue.js. Przydatna może okazać się również wiedza na temat REST API, Vue CLI i klientów FTP, np. darmowym FileZilla.

Czego potrzebujesz?

  • Strony WWW opartej o WordPressa, na którą będziesz implementować Vue.js.
  • Zainstalowanych wtyczek Advanced Custom Fields, Custom Post UI, ACF to Rest API.
  • Zainstalowanego Node.js, Vue CLI oraz terminala.
  • Klienta FTP, np. FileZilla i dostępu do serwera FTP.
  • Edytora kodu, np. Visual Studio Code.

Czego się nauczysz?

Dzięki niniejszemu poradnikowi nauczysz się, jak stworzyć aplikację Vue.js, a następnie zaimplementować ją jako wtyczkę do swojej strony opartej o WordPressa. Na potrzebę poradnika przygotowałem następujące zadanie: wykonasz wtyczkę do WordPressa zbudowaną przy pomocy Vue.js, która korzysta z WordPress Rest API do wyświetlania dziennego menu (7 najbliższych dni) dla restauracji.

Krok 1 – Konfiguracja CPT UI

Wejdź do panelu administracyjnego swojego WordPressa i otwórz wtyczkę „CPT UI” a następnie „Add New Post Type” i wpisz podane poniżej wartości:

Dodawanie nowego postu w CPT UI

Poniżej znajduje się sekcja dodatkowych ustawień. O ile sekcja „Additional Labels” jest opcjonalna, o tyle w sekcji ustawień upewnij się, że w polu „Show in REST API” wybrana jest wartość „True”. Następnie zejdź do kolejnego pola tekstowego „Rest API base slug” i wpisz tutaj część URL, do którego będziesz odwoływać się w późniejszym etapie.

szczegółowe ustawienia CPT UI

Kolejno, poniżej znajduje się możliwość wybrania ikony jako Menu Icon – możesz wybrać wygląd ikony na stronie WordPressa. Ikona wyświetlać się będzie w sekcji w panelu administratora. Następnie kliknij poniżej przycisk „Save Post Type” i przejdź do „Pola własne”, które przychodzą do Ciebie wraz z wtyczką Advanced Custom Fields.

Krok 2 – Konfiguracja Advanced Custom Fields

Czas zająć się opcjami wtyczki. Po wejściu w „Pola własne” w Advanced Custom Fields w panelu administratora WordPressa dodaj nową grupę pól:

dodawanie nowej grupy pól

W tytule nowych grup pól dodaj Oferty dnia (oczywiście możesz wpisać dowolną nazwę grupy, ale ta wydaje się odpowiednia dla Twojego zadania). Następnie dodaj nowe pola (przy tworzeniu pól zwróć uwagę na nazwę pola – do tej wartości będziesz odwoływać się podczas tworzenia aplikacji). Na potrzeby tworzonej aplikacji będą Ci potrzebne następujące pola:

  • Data (pole typu data z niestandardowym zwracanym formatem „Y,m,d”) – pamiętaj o zachowaniu zwracanego formatu. W stworzonej później aplikacji Vue.js będziesz z niego korzystać do formatowania daty i sprawdzenia ważności oferty,
  • Pierwsze danie (domyślne pole typu tekst),
  • Drugie danie (domyślne pole typu tekst),
  • Cena zestawu (domyślne pole typu liczba),

Po dodaniu powyższych pól przejdź poniżej na sekcję „Lokacja” i ustaw następujący warunek:

Warunek sekcji Lokacja w ACF

Pozostałe elementy ustawień pozostaw domyślnie. Następnie przejdź do dodanej pozycji w menu administratora i dodaj pierwszą ofertę dnia. Ja zdecydowałem się na zupę pomidorową oraz kotleta schabowego z frytkami i zestawem surówek, ale liczę na Twoją kreatywność.

Krok 3 – utworzenie nowego projektu za pomocą Vue CLI

Aby utworzyć nowy projekt za pomocą Vue CLI, wpisz w terminalu następujące polecenie:

vue create nazwa_projektu

Zwróć uwagę, że nazwa_projektu będzie nazwą aplikacji oraz nowo utworzonego folderu.

Następnie wybierz za pomocą strzałek [Vue 2] babel, eslint. Babel to łańcuch narzędzi, używany do konwersji kodu ECMAScript 2015 (ES6) na wstecznie kompatybilną wersję JavaScript w obecnych i starszych przeglądarkach lub środowiskach. ESLint analizuje Twój kod, aby uczynić go bardziej spójnym i uniknąć błędów. Listę zasad dotyczących kodów weryfikowanych przez ESLint znajdziesz tutaj.

widok wyboru ustawień

Po prawidłowym zakończeniu instalacji otrzymasz następujący komunikat:

komunikat po prawidłowej instalacji

Przejdź do wskazanego przez Vue CLI folderu (pamiętaj, że folder utworzony zostanie domyślnie w lokalizacji, w której aktualnie znajdujesz się w terminalu).

Wykorzystanie Vue.js jako wtyczki do WordPressa to ciekawe rozwiązanie do zastosowania przy kolejnych nowych projektach. Pozwoli Ci ono znacząco przyspieszyć pracę – gotową wtyczkę możesz z łatwością przenosić pomiędzy instancjami tego CMSa.

W dhosting.pl lubimy rozwiązania, które przyspieszają i ułatwiają pracę, dlatego też stworzyliśmy Elastyczny Web Hosting – unikatową usługę, dzięki której nie musisz poświęcać czasu na monitorowanie zasobów niezbędnych dla Twoich stron WWW.  Otrzymasz wysokie parametry gwarantowane, czyli 1 GHz CPU, 2 GB RAM oraz 50 GB NVMe, a jeśli w którymkolwiek momencie Twoje witryny będą potrzebować więcej, opcja elastycznego skalowania automatycznie, bez konieczności kontaktu z supportem, przydzieli Ci dodatkowe zasoby. Zapewnią one płynność w działaniu wszystkich Twoich stron niezależnie od ich obciążenia.

WYPRÓBUJ HOSTING

Krok 4 – tworzenie nowych komponentów i środowiska produkcyjnego

Usuń domyślnie utworzony komponent HelloWorld.vue oraz usuń jego importowanie w pliku App.vue wraz z jego wskazaniem w sekcji komponentów. Następnie w folderze głównym swojej aplikacji utwórz plik o nazwie vue.config.js i wklej do niego następujący kod:

module.exports = {
    filenameHashing: false,
}

Dzięki niemu podczas kompilowania aplikacji zniknie hash w nazwie plików, które zostaną skompilowane. Hashowanie plików nie jest potrzebne do Twojego projektu, ponieważ nie będziesz korzystać z domyślnie tworzonego przy kompilacji pliku index.html. Więcej możliwości konfiguracyjnych znajdziesz w oficjalnej dokumentacji Vue CLI.

Na tym etapie utwórz w folderze komponentów dwa pliki: OfferBox.vue oraz SingleOffer.vue. Twoja struktura w folderze głównym powinna wyglądać w następujący sposób:

wygląd struktury folderu Vue.js

Teraz dodaj poniższy kod do komponentu głównego App.vue. Szablon pliku .vue składa się z trzech elementów:

  • sekcji template, w której znajduje się Twój kod HTML oraz inne komponenty .vue,
  • sekcji script zawierającej kod JavaScript,
  • sekcji style, w której znajduje się kod CSS. (Sekcja style może zawierać atrybut scoped, aby ograniczyć wyświetlanie stylów tylko do tego komponentu.)
<template>
  <div id="app">
    <offer-box />
  </div>
</template>

<script>
import OfferBox from './components/OfferBox.vue'
 
export default {
  name: 'App',
  components: {
    OfferBox
  }
}
</script>
<!-- <style scoped> aby ograniczyć wyświetlanie CSS tylko dla tego komponentu -->

<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap');
#app {
  font-family: Roboto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: 16px;
  margin-top: 60px;
}
h3{
  margin: 5px 0;
}
p {
    margin: 5px 0;
}
 
</style>

Dodaj następujący kod do komponentu OfferBox.vue:

  • w sekcji template dodaj div o klasie container, w którym wyświetlana będzie karta z ofertą, bądź informacją o oczekiwaniu na powrót danych z zapytania dokonanego po zamontowaniu komponentu,
  • do drugiego diva dodaj wcześniej utworzony komponent single-offer oraz wykonaj iterację pobranych danych za pomocą dyrektywy v-for (konieczne jest przy tej dyrektywie dodanie parametru key). Komponent OfferBox przekazuje dane do komponentu single-offer.

Pamiętaj, aby zmienić w metodzie fetchOffer() link na swoją domenę z zainstalowanym WordPressem.

<template>
  <div class="container" v-if="menu">
    <div class="card" v-if="isLoading">Pobieram ofertę</div>
    <div class="card" v-for="item in checkValidDate" :key="item.id">
      <single-offer
        :date="item.acf.date"
        :soup="item.acf.soup"
        :main="item.acf.main"
        :price="item.acf.price"
      />
    </div>
  </div>
</template>

<script>
import SingleOffer from "./SingleOffer.vue";
export default {
  components: { SingleOffer },
  data() {
    return {
      menu: null,
      isLoading: false,
    };
  },
    // wywołanie funkcji fetchOffer() po zamontowaniu komponentu
  mounted() {
    this.fetchOffer();
  },
  methods: {
    // pobranie danych z WordPress Rest API z użyciem ACF
    async fetchOffer() {
      this.isLoading = true;
      await fetch("https://twoja-domena.pl/wp-json/wp/v2/oferty?_fields=acf")
        .then((response) => response.json())
        .then((data) => (this.menu = data));
      this.isLoading = false;
    },
    // funkcja na potrzebę sprawdzenia różnicy w dniach
    checkDayDiffrence(futureDate){
        let currentDay = new Date()
        let futureDay = new Date(futureDate)
        const oneDay = 1000*60*60*24
        const diffrence = futureDay.getTime()- currentDay.getTime();
        const diffrenceDays = Math.round(diffrence / oneDay);
        return diffrenceDays
    }
  },
    computed: {

      // sprawdzamy, czy róznica między datami znajduje się w zakresie od 7 dni do -1 (zastosowanie -1 pozwala na wyświetlanie oferty z bieżącego dnia)
        checkValidDate(){
            let filteredMenu = this.menu.filter(item => this.checkDayDiffrence(item.acf.date) <= 7 && this.checkDayDiffrence(item.acf.date) >= -1 )
            return  filteredMenu
        }
    }
};
</script>

<style>
.container {
  display: flex;
  align-content: center;
  align-items: center;
  flex-direction: column;
  justify-content: space-around;
}
.card {
  color: inherit;
  padding: 20px;
  text-align: center;
  border-radius: 10px;
  margin-bottom: 2em;
 
}
</style>

Dodaj następujący kod do komponentu SingleOffer.vue:
(Komponent SingleOffer.vue otrzymuje dane od nadrzędnego komponentu oraz zwraca datę poprawną do wyświetlenia.)

<template>
  <div>
    <div class="header">Oferta na dzień: {{parseDate.day }}.{{parseDate.month + 1}}.{{parseDate.year}}</div>
    <div class="single-box" >
      <h3 class="title">Zupa</h3>
      <p>{{ soup }}</p>
      <h3 class="title">Drugie danie</h3>
      {{ main }}
      <h3 class="title">Cena</h3>
      <p class="price">{{ price }} PLN</p>
    </div>
  </div>
</template>

<script>
export default {
  props: {
      soup: String,
      main: String,
      price: String,
      date: String,
  },
  computed: {
    // zwraca poprawnie sformatowaną date do wyświetlenia - funkcja natywna 	getMonth() zwraca wartość od 0 do 11 stąd przy wyświetlaniu dodaj do      zwróconej przez funkcję wartości 1
    parseDate(){
      let currentDay = new Date(this.date)
      return {day: currentDay.getDate(), month: currentDay.getMonth(), year: currentDay.getFullYear()}
    }
  }
};
</script>

<style scoped>
.single-box {
  width: 400px;
  height: 350px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
  font-size: 1.2em;
}
.header {
  font-size: 1.5em;
  background-color: #c94141;
  color: aliceblue;
  padding: 20px;
  margin-bottom: 20px;
}
.price {
  font-size: 1.5em;
}
</style>

Na tym etapie uruchom aplikację i sprawdź połączenie z WordPress Rest API. W terminalu wpisz polecenie:

npm run serve

Za pomocą tej komendy uruchomisz lokalny serwer deweloperski. Będzie on dostępny pod wskazanym na terminalu adresem. Otwórz jeden z dwóch wyświetlanych adresów za pomocą crtl + lpm i przejdź do przeglądarki.

Jeżeli dodana oferta znajduje się na stronie, to znaczy, że wszystko działa prawidłowo i możesz przejść do kompilacji swojej aplikacji i przygotowania jej jako wtyczki do importu na serwer.

Krok 5 – Kompilacja aplikacji i tworzenie wtyczki Vue.js

Do kompilacji użyj polecenia w terminalu:

npm run build

Pliki umieszczone zostaną domyślnie w folderze dist – w głównym folderze aplikacji. W głównej lokalizacji aplikacji utwórz nowy folder i nazwij go rest-auto-menu. W środku utwórz plik .php, który będzie tożsamy z nazwą wtyczki – rest-auto-menu.php. Do pliku dodaj następujący kod:

<?php
/**
 * Plugin Name:         Nazwa wtyczki
 * Plugin URI:          https://dhosting.pl
 * Description:         Automatyczne menu dla restauracji
 * Version:             1.0.0
 * Author:              Jan Kowalski
 * Author URI:          https://dhosting.pl
 * 
 * Pamiętaj, aby zmienić nazwę folderu, w którym znajduje się ten plik, i tego pliku, tak aby odpowiadała nazwie Twojej wtyczki. Nazwy muszą być takie same, aby WordPress wiedział, gdzie szukać.
 */
 
function load_vuescripts() {
    wp_enqueue_style( 'vue_wp_styles', plugin_dir_url( __FILE__ ) . 'dist/css/app.css' );
    wp_register_script( 'vue_wp_compiled', plugin_dir_url( __FILE__ ) . 'dist/js/app.js', true );
    wp_register_script( 'vue_wp_dependencies', plugin_dir_url( __FILE__ ) . 'dist/js/chunk-vendors.js', true );
}
 
add_action( 'wp_enqueue_scripts', 'load_vuescripts' );
 
function attach_vue() {
    wp_enqueue_script( 'vue_wp_compiled' );
    wp_enqueue_script( 'vue_wp_dependencies' );
 
    return "<div id='app'></div>";
}
 
add_shortcode( 'rest_auto_menu', 'attach_vue' );
?>

Zwróć uwagę na ostatnią funkcję add_shortcode(). Pierwsza część funkcji odpowiada za nazwę skrótu, dzięki któremu umieścisz aplikację w wybranym przez siebie miejscu na WordPressie. W powyższym przykładzie będzie to [vue_automenu] (nazwa ta może być dowolna). Więcej o tej funkcji przeczytasz tutaj. Następnie do wcześniej utworzonego folderu rest-auto-menu dodaj foldery dist. Struktura folderu powinna wyglądać w następujący sposób:

wygląd struktury folderów

Cały folder rest-auto-menu wgraj za pomocą, np. FileZilla do folderu wp-content/plugins, następnie aktywuj swoją wtyczkę. Kiedy wtyczkę masz już gotową, możesz dodać ją za pomocą, np. Gutenberga:

kod guttenberg

W efekcie Twoja aplikacja jest już dostępna po publikacji danej strony zawierającej skrót do Twojej wtyczki. Vue.js jako wtyczka do WordPressa daje Ci możliwość korzystania z nowoczesnych rozwiązań w ekosystemie WordPressa, które mogą znacząco przyspieszyć pracę nad Twoim projektem. Dodatkowo w łatwy sposób możesz przenieść gotową wtyczkę pomiędzy instancjami WordPressa, bądź wykorzystać kod w przyszłości, przy innym projekcie.

Aby zachować sprawiedliwość, muszę wspomnieć o kilku wadach tego rozwiązania. Po każdej aktualizacji kodu wtyczki należy wykonać polecenie build, a następnie przenieść foldery zawierające pliki .css i .js za pomocą klienta FTP na serwer. Dodatkowo każda aktualizacja związana będzie z koniecznością wyczyszczenia plików cache, o ile takie cache plików dostępne jest na stronie.

Oto, jak wygląda efekt Twojej pracy:

wygląd menu stworzonego przez Vue.js jako wtyczkę do WordPressa

Podsumowanie

Połączenie Vue.js z WordPressem poszerza dostępne możliwości i ułatwia pisanie zaawansowanych aplikacji, które z łatwością możesz wykorzystać na swojej stronie opartej o WordPressa. Pamiętaj, że blog zaprezentowany w powyższym poradniku dla celów edukacyjnych zawiera tylko jedną możliwość wprowadzenia funkcjonalności Vue.js do WordPressa. Utworzoną w tym poradniku wtyczkę można z łatwością rozwinąć, np. dodać funkcjonalność wyświetlania oferty dnia w przód według utworzonego nowego pola Advanced Custom Fields. Dzięki Vue.js możesz wykorzystać na swojej stronie wcześniej zbudowane komponenty, zaoszczędzając przy tym czas na zbudowanie takiej samej funkcjonalności w języku PHP.

Roman Lorent

Autor artykułu: Mikołaj Grendzisz

Vue.js Developer. Twórca stron internetowych oraz aplikacji internetowych opartych o Vue.js – aktualnie do rozliczeń kierowców taxi na popularnych aplikacjach. Dodatkowo od wielu lat tworzy i modernizuje strony oparte o WordPressa. Ponadto chętnie dzieli się swoją wiedzą na tematycznych forach.