I’ve covered using the WordPress REST API with AngularJS in the past for Torque because I like it and have used it quite a bit. However, I have been using Laravel a lot lately, and the Laravel ecosystem has embraced VueJS as the front-end framework. That encouraged me to try it out and I’ve been impressed by its simplicity.
My first real experience using VueJS was for the Caldera Forms front-end entry viewer. I had been experimenting with new ways of handling UI and I found VueJS to be the fastest to learn and loved the results.
In this article, I’m going to show you some VueJS basics to display and edit WordPress contents via the REST API.
Why VueJS?
In this tutorial, you will learn how with less than 25 lines of JavaScript and very few new concepts to create a reactive application that shows WordPress content, with a live updating editor. With a little more work you could make this same code render both server-side and in the browser to ensure web crawlers — like search engines — and browsers without JavaScript could properly use the site.
That’s pretty cool, right? I’m also not going to require you to learn ES6, or any complicated build tools. Yes, I think you should learn ES6, and those build tools. For a big, complicated application, you might consider React or Angular 2, but VueJS is well suited for those types of applications as well.
Getting Started With VueJS
Let’s get started with a few simple examples of how to show a single post from the WordPress REST API. Then we’re going to add an editor. This editor will illustrate how easy it is to create reactive apps and what that means. You will see that when you type in the form fields, the HTML elements bound to the same parts of the model — in this case the post — will live update. More importantly, the model in the app will change, allowing us to send that back to WordPress, via the REST API to save the content.
In the example code, I’m going to be using jQuery’s AJAX API to get and send content to WordPress. You really could use any AJAX API, depending on your needs.There are other things you could use for this, but I don’t think it makes sense to teach multiple technologies at once, so let’s stick to the standard.
The Vue Constructor
To get VueJS started, we create a new instance using the Vue constructor and tell it what data to use and what HTML element wraps the section of the DOM we are working with. Let’s start with a basic example that uses mock data, formatted the same as a WordPress post. Take a look:
var ex1 = new Vue({ el: '#post', data: { post: { title: { rendered: 'Hello World!' }, content: { rendered: "<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!<\/p>\n", } } } });
The object we pass to the constructor has two indexes. The first is “el” this represents the element that VueJS binds to. The second is “data” this is the data that we use to render the template inside of that element. I have pasted the title and content of WordPress’ Hello World post in the format it would be returned by the REST API.
Now in an HTML document that includes VueJS (here is a CDN link: https://unpkg.com/[email protected]/dist/vue.min.js) you can add this HTML to serve as template:
<div id="post"> <article> <header> <h1 class="post-title"> {{post.title.rendered}} </h1> </header> <div class="entry-content"> {{post.content.rendered}} </div> </article> </div>
Notice that the outermost HTML element has the id “post” and that corresponds to the value we set in the JavaScript — “#post” for “el.” Also, this mustache style templating should look familiar if you’ve ever worked with templating languages like Mustache or Handlebars or even the AngularJS framework.
This will show the post. But you will notice that the HTML tags in the post content are not rendered. By default, VueJS doesn’t trust HTML tags, but if you’re using a trusted API, then you can use v-html directive to bind HTML to an element. Here our HTML is rewritten so that the HTML tags in the post content are shown:
<div id="post"> <article> <header> <h1 class="post-title"> {{post.title.rendered}} </h1> </header> <div class="entry-content" v-html="post.content.rendered"></div> </article> </div>
That’s the basics to show data.
Adding Form Inputs
Now that we have content, let’s add some form inputs to edit that content. We actually don’t need to change our JavaScript in any way yet. All we need to do is create the inputs in the HTML and use the v-model attribute to bind the HTML input to the same part of the model as the HTML elements used for display:
<div id="post"> <article> <header> <h1 class="post-title"> {{post.title.rendered}} </h1> </header> <div class="entry-content" v-html="post.content.rendered"></div> </article> <form> <div> <label for="post-title-edit"> Post Title </label> <input id="post-title-edit" v-model="post.title.rendered"> </div> <div> <label for="post-content-edit"> Post Content </label> <input id="post-content-edit" v-model="post.content.rendered"> </div> </form> </div>
The HTML for the inputs is totally standard, except v-model. That attribute uses the same syntax, as the template, minus the mustache. When we run this, you can edit the post in the inputs and see the display update in real time. Again, no extra JavaScript needed.
Using AJAX To Connect VueJS To The WordPress REST API
So far we’ve been showing mock data with a form that can change the display of that data. In this section, we will replace that mock data with an AJAX call to the WordPress REST API to get a real post’s data. The next step will be to add a save button to the form. The save button will provide a practical example of how event handling works in VueJS as well as how to add a POST request back to the WordPress REST API to save the data.
Using the same HTML, update your JavaScript to get the post and then use the jQuery success callback to use that data to construct the Vue instance:
/** You should use wp_localize_script() to provide this data dynamically */ var config = { api: 'https://yoursite.com/wp/v2/posts/1', nonce: 'hiroy' }; /** GET post and then construct Vue instance with it **/ var ex3; $.get({ url: config.api }).success( function(r) { ex3 = new Vue({ el: '#post', data: { post: r } }); });
Now we have real data from WordPress. By waiting until jQuery AJAX is done, we avoid constructing the Vue instance without the data we need.
Event Handling
One of my favorite things about VueJS is event handling. The Vue constructor accepts an argument, which we haven’t used yet, called “methods.” This argument stages an object of functions that can be called using data-attributes in our HTML.
The v-click attribute can be used to tell VueJS which function defined in “methods” to call when a link, button, or submit input is clicked. Here is an updated template with a submit button in the form that calls the “save()” function:
<div id="post"> <article> <header> <h1 class="post-title"> {{post.title.rendered}} </h1> </header> <div class="entry-content" v-html="post.content.rendered"></div> </article> </div>
Now we will need to define that save() function and use it to POST the data back to WordPress:
/** You should use wp_localize_script() to provide this data dynamically */ var config = { api: 'http://forming.dev/wp/v2/posts/1', nonce: 'hiroy' }; /** GET post and then construct Vue instance with it **/ var ex4; $.get({ url: conf.api }).success( function(r) { ex4 = new Vue({ el: '#post', data: { post: r }, methods: { save: function(){ var self = this; $.ajax( { url: config.api, method: 'POST', beforeSend: function ( xhr ) { xhr.setRequestHeader( 'X-WP-Nonce', config.nonce ); }, data:{ title : self.post.title.rendered, content: self.post.content.rendered } } ).done( function ( response ) { console.log( response ); } ); } } }); });
Notice that the constructor now has a “methods” index. Inside of the methods, we can access the post using “this.post.” But inside of the jQuery.post() method, this will refer to the current jQuery instance. That is why the first thing I do is set the variable “self” equal to “this.” That way I can use self.post.title.rendered inside of the jQuery.post() to get the post title from the current model.
That Got Reactive Fast
If you’re like me, you’ve been watching the cool kids make really neat apps with React and other reactive frameworks, but we’re searching for a quick way, I hope this article has shown you that VueJS is the answer. We didn’t write a ton of code, Redux, some abstraction for HTML like JSX, or use any fancy build tools, or even use ES6.
Yes, you should learn those, and I would use Redux or Vue’s flux-like state manager for a serious app, but we just got started faster then you could set up webpack. I hope you will take this opportunity to explore the possibilities of VueJS and learn more about it. Soon, you’ll be building more complex apps with it, and using it as an excuse to learn ES6, Flux or Redux and other modern JavaScript tools.
To learn more about the REST API JavaScript frameworks, check out Caldera Learn.
17 Comments