Создание SPA на Vue.js поверх Headless WordPress

Spread the love

Перевод статьи Maxime LaBoissonniere: Build a Vue.js SPA on Top of Headless WordPress. Статья написана от первого лица то есть от имени автора Максима ЛаБуассоньера.

Я не могу поверить, что снова собираюсь написать статью о WordPress. На самом деле я шучу, так как в прошлый раз, когда я играл с WordPress REST API, я подумал, что на самом деле это довольно круто!

Это был настоящий глоток свежего воздуха, увидеть как мастодонт веб-индустрии, открывается для современных тенденций и новых парадигм.

Вот я и подумал: насколько было бы интересно использовать WordPress в качестве headless CMS с Vue.js фреймворком – моим любимым фронтенд фрейморком? И какой же ответ? Оказывается, все это очень интересно. В этой статье я хочу подробно рассмотреть этот стек.

Я расскажу о следующих шагах:

  1. Создание моделей с настраиваемыми полями в WordPress
  2. Создание пользовательской конечной точки для API REST WP (API URL)
  3. Настройка одностраничного приложения Vue.js
  4. Хостинг приложения

Но в начале, давайте определимся что такое «использование WordPress как headless CMS».

Использование WordPress в качестве headless бэкэнда

Monolithic CMS vs Headless CMS [source]

Что это значит?

Прежде чем углубляться в WordPress в качестве конкретного примера, давайте удостоверимся, что мы понимаем, что означает headless CMS.

Еще несколько лет назад мы были привычны к тому, что традиционные CMS работают определенным образом. То есть они управляют всем. Под этим я подразумеваю бэкэнд (управление данными/контентом, роли и разрешения, задачи администратора) и внешним интерфейсов то есть фронтендом (в большинстве случаев представления, генерируемые PHP) и естественно всем, что между ними.

Тем не менее, относительно недавно произошел значительный сдвиг благодаря росту современного фронтенд интерфейса. В огромной экосистеме, которая возникла вокруг нее, просто нет места для старых, монолитных CMS. Появились генераторы статических сайтов, микросервисы, ориентированные на API, и serverless архитектуры.

Это не значит, что что-то вроде WordPress должно исчезнуть. Это только означает, что он больше не должен управлять всеми частями веб-сайта. Почему так? Потому что есть инструменты, которые намного лучше выполняют определенные задачи, чем другие.

Итак, почему бы не использовать WordPress только для того, в чем он действительно хорош? Это именно то, что называется API-интерфейс WP JSON REST который был включен в его состав с момента выпуска WordPress 4.7. Он позволяет использовать контент, внедренный в бэкэнд WordPress, в во внешних приложениях, независимо от того, какая технология задействована.

Это изменяет правила игры.

Вы можете найти более подробное объяснение API WP REST в нашем первом посте на эту тему.

Зачем тебе это использовать?

Я уверен, что если вы разработчик с минимальным опытом работы с WordPress, вы уже видите мир новых возможностей, которые это приносит.

Основным недостатком WordPress (кстати, на который разработчики жаловались годами) было отсутствие свободы разработки и хлопоты, связанные с настройкой шаблонов. Но используя WordPress только как бэкэнд, эти проблемы выбрасываются в окно и с высокой скоростью:

→ Разработчикам возвращается свобода использования инструментов, которые они любят, на модульном уровне. Это позволяет масштабировать проекты только тогда, когда это необходимо, и, кстати, приводит к повышению производительности.

→ Работа с WP-шаблонами окончена. Подключите его по своему вкусу и не беспокойтесь о переопределении шаблонов на основе PHP. Намного проще создавать потрясающие пользовательские интерфейсы с нуля, которые затем могут использовать данные WordPress.

Следующая демонстрация подчеркнет эти преимущества. На Vue.js – мы создадим оболочку внешнего интерфейса, которую я буду использовать для создания своего приложения поверх WordPress.

Зачем использовать Vue.js с WordPress?

Связывание WordPress с JS-фреймворками позволяет нам использовать его в приложениях, там где в прошлом это было бы непросто. Подумайте о приложениях для нескольких устройств, IoT, прогрессивных веб-приложениях и других современных методах.

Помимо того факта, что я уже использовал React для моей первой демонстрации headless WP, есть много причин, по которым я бы предложил Vue.js всем, кто ищет подходящую среду интерфейса.

Основные вещи, которые вы услышите от людей о Vue, – это его модульность, скорость и высокая производительность.

Я рассказал больше о том, почему Vue.js правильный выбор в нашем блоге.

Выбор Vue.js

Как и вся экосистема JavaScript в целом, сообщество Vue расширяется с каждой минутой. Теперь есть инструменты, основанные на нем, для практически любых фронтенд-проектов. Вот основные из них, на которые следует обратить внимание:

  • Nuxt: Отличный фреймворк для создания статических сайтов, разработки одностраничных приложений (SPA) и рендеринга на стороне сервера. В этом уроке мы использовали его для создания статического сайта поверх headless CMS.
  • Gridsome: Vue.js эквивалент Gatsby. Работает на GraphQL для извлечения данных из любых источников, в том числе headless CMS. Он может генерировать прогрессивные веб-приложения (PWA).
  • VuePress: Минималистичный статический генератор сайтов на базе Vue, идеально подходящий для создания документации и небольших блогов.

Проблемы с SEO?

Отличительной чертой традиционного использования WordPress является то, что вам не нужно слишком беспокоиться о SEO; он в основном оптимизировано для этого по умолчанию. Обычно есть проблемы с использованием SEO с JS-фреймворками.

Но давайте закроем этот вопрос, раз и навсегда. На самом деле вы можете получить отличные результаты в SEO и с Vue.js, если вы правильно с этим справитесь. Рендеринг на стороне сервера с Nuxt.js – это один из способов, но вы также можете использовать простой сервис предварительного рендеринга, как мы сделали это здесь.

Так же лучшая производительность и UX помогут вам улучшить ваши результаты в SEO!

Headless WordPress, связанный с Vue.js SPA

Контекст

Наша команда расширяется в размерах, но также и по городах, где живут некоторые из наших членов команды. Итак, давайте допустим, что нам становится все труднее помнить, где все находятся, когда мы растем. И я создам приложение, чтобы оставлять точки маркеров на интерактивной карте и следить за местонахождением каждого из команды.

Я покажу вам, как создать адаптивный Vue SPA, чтобы сделать именно это. Бэкэнд очень похож на мой пост, посвященный React с WordPress, но я буду использовать его совершенно по-другому с приложением на Vue.js.

Необходимые условия

  • Работающий экземпляр WordPress
  • Базовые знания Vue
  • Бесплатный аккаунт MapBox

1. Создание моделей с настраиваемыми полями в WordPress

Давайте сразу перейдем прямо в админку WordPress.

Я буду использовать плагин ACF (Advanced Custom Fields) для создания наших пользовательских объектов для демонстрации.

Этот плагин позволяет добавлять настраиваемые поля в нативные сущности WordPress, такие как посты (posts). Он тщательно протестирован, стабилен и облегчает нам добавлении пользовательских данных на страницу.

Вы можете легко установить его, используя вкладку «Плагины» на панели инструментов WordPress. Вот что вы должны найти:

Объявите настраиваемые поля, щелкнув на новый раздел настраиваемых полей на левой панели.

Для этого варианта использования вам понадобятся четыре атрибута: две координаты, имя и изображение. Вот как это выглядит на дашбоард панели:

Теперь, когда вы можете добавлять пользовательские данные в свои записи WordPress, давайте использовать их для создания маркеров, показывающих, где живут члены команды. Вот список недавно созданных сообщений:

2. Создание пользовательской конечной точки

Теперь, когда у вас есть ваши данные, вам нужно открыть их для всеобщего использования через API JSON REST.

Для этого создайте пользовательскую конечную точку. Откройте папку WordPress и откройте файл functions.php. Здесь вы зарегистрируете свою новую конечную точку.

Добавьте следующие строки в конец файла:

function  markers_endpoint( $request_data ) {
    $args = array(
        'post_type' => 'post',
        'posts_per_page'=>-1, 
        'numberposts'=>-1
    );
    
    $posts = get_posts($args);
    foreach ($posts as $key => $post) {
        $posts[$key]->acf = get_fields($post->ID);
    }
    return  $posts;
}
    
add_action('rest_api_init', function() {
    register_rest_route( 'markers/v1', '/post/', array(
        'methods' => 'GET',
        'callback' => 'markers_endpoint'
    ));
});

Метод add_action создает пользовательскую конечную точку и регистрирует ее через ловушку (hook) rest_api_init. После вызова конечной точки будет выполнен обратный вызов, который добавит ваши настраиваемые поля под ключом acf.

Теперь, когда отображение работает должным образом, не стесняйтесь зайти на новую конечную точку REST по адресу: /wordpress/wp-json/markers/v1/post.

Вот структура, которую вы должны увидеть после GET запроса, обратите внимание на новое поле ACF:

[
    {
        "ID": 19,
        "post_author": "1",
        "post_date": "2019-03-14 15:48:40",
        "post_date_gmt": "2019-03-14 19:48:40",
        "post_content": "",
        "post_title": "Chuck",
        "post_excerpt": "",
        "post_status": "publish",
        "comment_status": "open",
        "ping_status": "open",
        "post_password": "",
        "post_name": "chuck",
        "to_ping": "",
        "pinged": "",
        "post_modified": "2019-03-14 15:48:41",
        "post_modified_gmt": "2019-03-14 19:48:41",
        "post_content_filtered": "",
        "post_parent": 0,
        "guid": "http:\/\/localhost\/wordpress\/?p=19",
        "menu_order": 0,
        "post_type": "post",
        "post_mime_type": "",
        "comment_count": "0",
        "filter": "raw",
        "acf": {
            "Name": "Chuck",
            "image": "http:\/\/localhost\/wordpress\/wp-content\/uploads\/2019\/03\/charles-snipcart.png",
            "longitude": "49.8951",
            "Latitude": "97.1384"
        }
    }, ...
]

3. Настройка Vue SPA

Давайте использовать эти свежеиспеченные данные, чтобы сделать их полезными.

Чтобы создать свой проект, используйте Vue CLI. Если у вас его еще нет, вы можете легко установить его с помощью npm install -g @vue/cli

Затем создайте свой проект: vue create markers.

Первое, что нужно сделать, это получить данные из API непосредственно в вашем компоненте App. Для этого просто добавьте следующее объявление в компонент:

<template>
  <div id="app">
        
    <div class="badge-container">
      <div v-for="badge in markers" :key="badge.name">
        <Badge :name="badge.name" :image="badge.image" />
      </div>
    </div>
    <Map v-if="markers.length > 0" :markers="markers" />
        
  </div>
</template>
<script>
import Badge from './components/Badge.vue'
import Map from './components/Map.vue'
export default {
  name: 'app',
  data(){
    return {
      markers: []
    }
  },
  components: {
    Badge,
    Map
  },
  mounted(){
    fetch('https://wordpress-vue.herokuapp.com/index.php/wp-json/markers/v1/post')
      .then((r) => r.json())
      .then((res) => this.markers = res.map(x => x.acf));
  }
}

Если вы не знакомы с хуком жизненного цикла mounted компонента Vue, я настоятельно рекомендую вам почитать эту документацию.

Теперь, когда у вас есть данные, давайте создадим первый компонент (в папке /components), который называется badge.

Внесите в него следующее содержимое:

<template>
  <div class="badge" :id="name">
    <img :src=img width=500/>
    <h2>{{ name }}</h2>
  </div>
</template>
    
<script>
export default {
  name: 'Badge',
  props: {
    Name: String,
    Image: String
  }
}
</script>
    
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
    
</style>

Давайте вернемся обратно в компонент App и импортируем новый компонент import Badge from ‘./components/Badge.vue’.

Зарегистрируйте его непосредственно в объекте компонента с помощью:

components: {
    Badge
  }

Теперь давайте создадим новый компонент: Map.vue.

Здесь я буду использовать Mapbox для визуализации карты. У них есть хороший бесплатный доступ, аккуратная и полная документация … Больше я ничего не могу просить. Создав учетную запись, вы сможете получить доступ к токену доступа непосредственно на домашней странице панели управления: https://account.mapbox.com/.

Во-первых, добавьте JS и CSS Mapbox прямо в ваш файл index.html:

<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.1/mapbox-gl.css' rel='stylesheet' />

Затем определите ваш компонент следующим образом:

<template>
  <div>
      <div id='map' class='map'> </div>
  </div>
</template>
    
<script>
    
export default {
  name: 'Map',
  mounted(){
    
    window.mapboxgl.accessToken = "{YOUR_MAPBOX_ACCESS_TOKEN}";    
    
    var map = new window.mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/dark-v9',
        center: [-81.4608, 48.4758], 
        zoom: 4
    });
    
    map.on('load', (() => {
    
        this.markers.forEach(function(marker) {
            var el = document.createElement('div');
            el.className = 'marker';
    
            new window.mapboxgl.Marker(el)
                .setLngLat([parseFloat(marker.latitude), parseFloat(marker.longitude)])
                .addTo(map);
        });
    
        this.markers.forEach((x) => {
            document.getElementById(x.name)
                .addEventListener('click', () => {
                    map.flyTo({
                        center: [parseFloat(x.latitude), parseFloat(x.longitude)],
                        zoom: 9
                    })
                ;}
            )
        })
    
    }).bind(this));
  },
  props: {
   markers: Array
  }
}
</script>
    
<style>
.marker {
  background-image: url('./../assets/mapbox-icon.png');
  background-size: cover;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  cursor: pointer;
}
</style>

Как видите, единственные переменные, которые вам нужно передать, это маркеры. Точнее массив, содержащий всю информацию о наших маркерах. Вам нужно привязать этот процесс к map.on ‘load’, чтобы вы не пытались добавить что-либо на карту, пока она не будет готова к получению информации.

Затем мы создаем свои маркеры (используя фоновое изображение, определенное в CSS) и добавляем их на карту.

Последнее, что мы делаем, это добавляем слушателей событий addEventListener, чтобы карта перемещалась к нужному маркеру, когда кто-то нажимает на значок.

Этого должно быть достаточно на данный момент. Вы можете добавить или удалить маркеры непосредственно на своем бэкэнд на WordPress, и приложение будет загружать их соответствующим образом. Попробуй сами!

4. Хостинг для демо

Чтобы сделать это публичным, мы должны где-то разместить его. Чтобы сделать это дешево, вам придется разместить свою базу данных и экземпляр WordPress в разных экосистемах. Например, я буду использовать Heroku, но так как бесплатный уровень поддерживает только эфемерную файловую систему, мне также придется разместить базу данных на другом сервере.

Размещение базы данных MySQL может осуществляться тысячами способов, поэтому я оставлю эту часть на ваше усмотрение и сосредоточусь на размещении только экземпляра WordPress и приложения Vue.

Вот как это сделать с Heroku:

Зайдите в их панель и создайте новый проект.

Как только это будет сделано, добавьте их репозиторий в качестве удаленного к вашему проекту. Вы можете увидеть, как это сделать прямо на панели инструментов.

Затем измените строки подключения к базе данных. Это можно сделать очень легко в файле wp-config.php со следующими атрибутами:

define( 'DB_NAME', '{YOUR_DB_NAME}' );
define( 'DB_USER', '{YOUR_DB_USER}' );
define( 'DB_PASSWORD', '{YOUR_DB_PASSWORD}' );
define( 'DB_HOST', '{YOUR_DB_HOST}' );

Поскольку вы, вероятно, начали разработку на своем локальном хосте, вам, вероятно, придется изменить URL своего сайта, поскольку он больше не будет локальным. Есть много способов сделать это, поэтому я позволю вам выбрать путь, который вы предпочитаете, или как написано в официальных документах.

Ура, вам нужно только разместить ваше приложение Vue, и все будет готово!

Я воспользовался бесплатным аккаунтом Netlify, что означает, что он перенесет демо в публичное репо и подключит его к проекту Netlify.

Итак, после того, как запушили код, перейдите на панель инструментов Netlify и используйте следующую конфигурацию для сайта:

Taдa!

Просто измените свой метод fetch, чтобы он указывал на ваш новый экземпляр Heroku (а не на ваш локальный хост), и все готово.

Приложение будет извлекать данные из вашего экземпляра Heroku, который сам подключен к вашей удаленной базе данных. Он проанализирует данные и отправит их обратно клиенту, чтобы отобразить маркеры на карте.

Live demo & GitHub repo

Перейти на демо

Посмотреть репозитарйи на GitHub

Заключение

Мне нравится работать с WordPress как с headless CMS каждый раз, когда я это пробую! Vue.js всегда подразумевает замечательный опыт разработки, поэтому мне очень понравилось создавать эту демонстрацию.

Mapbox также впечатляет. Это был мой первый раз, когда я игрался с Maps API, и это отличный сервис, с хорошей документацией. Всегда круто пробовать что-то новое. 🙂

Должно быть, я потратил 2-3 часа на все это!

Вы можете попробовать свою интеграцию, чтобы определить более сложные объекты, что займет немного больше времени, но сама идея останется прежней! Таким образом, мы могли бы визуализировать гораздо больше, чем просто маркеры, и сделать нашу карту более насыщенной.

Любые вопросы? Не стесняйтесь оставлять комментарии, чтобы высказать свои мысли, отзывы и вопросы. Если вам понравился этот пост, уделите секунду 👏 или поделитесь им в Twitter!

Была ли вам полезна эта статья?
[14 / 4.7]

Spread the love
Подписаться
Уведомление о
guest
4 Комментарий
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Никита
4 лет назад

Спасибо за статью, интересен так же вопрос, на сколько рационально делать информационный портал или блог в связке Vue + WordPress?

Виктор
Виктор
3 лет назад
Reply to  Никита

Пост интересный, но тоже вызывает много вопросов. К сожалению для себя я не увидел практической ценности использования WordPress как с headless CMS. Можеьт я не доконца понял прицнып. Но действительно, есть ли смысл так заморачиваться при создании информационного портала или интернет магазина на WC? Хотя Woocommerce тоде имеет REST API.

Аноним
Аноним
1 год назад

Спасибо за статью. Как раз хочу сделать простой личный сайт с удобной админкой. WP отлично с этим справится

Артём
Артём
10 месяцев назад

Так и не понял как был решён вопрос с SEO ведь с сервера поисковик не получит конечных данных как я понял…

Last edited 10 месяцев назад by Артём