Build a Simple Blog Reader

Our goal is to create a simple app to display a list of posts from a WordPress.com blog. Clicking on any of the post titles in our list will open the full blog post in another section of the page.

Resources

Getting Started

  1. Visit the Github repo to clone or download the code.
  2. Run NPM Install / uncomment CDN links
  3. Open main.js and begin reading.

I have added steps to main.js which correspond to some explanations below. Read through the code and the matching explanations to get a better understanding of how everything works before moving onto the challenges.

The Code

I use ES6 a lot, so you should get familiar with it. See the links to Babel above.

The Vue Instance

Sometimes it helps to see something written a different way to understand what’s going on; the documentation always shows a new Vue instance being created this way:

new Vue({
    // code
}) 

Here a new Vue object is being created using an object that is passed in as an argument. This object is the options object and is required. It would be just as valid to write:

const options = {
    // code
}

new Vue(options)

Not ground breaking, but I find it helpful to view code from a variety of angles to help it sink in a bit better. If it helps you to write your code in an alternative way, then go for it. I tend to divide my code up a lot to help with readability.

Steps 1-2 – Fetch Our Blog Posts

The ‘created’ property on the options object is called a life cycle hook. We’ll use this to fire of our initial request to get the blog data.

Step 3 – Display Our Blog Posts

The response contains an array of posts at ‘resp.body.posts’. Uncomment the debugger and refresh the app if you want to see what the response object looks like.

We save the returned data to ‘this.posts’ which references the posts array on our data object.

data: {
    posts: []
}

Our view will automatically update when the data is set to the posts array.

The v-for Directive

v-for directive documentation

In our index.html you’ll see how we’ve setup our view to iterate over this list of posts and display the title.

<li v-for="post in posts" @click="selectPost(post.ID)">{{post.title}}</li>

The v-for directive loops over the ‘posts’ array. Each item in the array is refered to as ‘post’.

If our posts array was named ‘blogPosts’ then our code would look this:

data: {
    blogPosts: []
}
<li v-for="post in blogPosts" @click="selectPost(post.ID)">{{post.title}}</li>

And we don’t have to name each item, ‘post’. We could name them ‘blogPost’ or ‘singlePost’. It doesn’t matter.

Steps 4-5 – Click to View Post

At this point our app has started and we’ve displayed a list of the posts we’ve fetched from the WordPress.com API.

In our index.html we’ve attached a click handler to our post titles.

<li v-for="post in posts" @click="selectPost(post.ID)">{{post.title}}</li>

The @click could be written another way, too.

<li v-for="post in posts" v-on:click="selectPost(post.ID)">{{post.title}}</li>

Another reason to love Vue is all the nice shorthands we’re given to make our lives a bit easier.

This link of code connects to the ‘selectPost’ function found in our main.js.

methods: {
        // Step 4: Click on a post title to activate this function.
    selectPost(postID) {
      this.$http.get('https://public-api.wordpress.com/rest/v1.1/sites/stearns.wordpress.com/posts/' + postID)
        .then((resp) => {

          // Step 5: Save our data to the selectedPost property to update the view.          
          this.selectedPost = resp.body
        })
    }
}

You’ll notice we’re passing in the post.ID. Again, if we had named this item blogPost, or singlePost, we’d write our html like this:

<li v-for="singlePost in posts" @click="selectPost(singlePost.ID)">{{singlePost.title}}</li>

Each ‘singlePost’ (or ‘post’ in our index.html) is an object with an ID property. This property value is passed into our selectPost function where it’s appended to a new URI to request the details for the post that matches that ID.

Just like with our initial fetch for the posts array, we save the returned data to our selectedPost property on the data object.

data: {
    posts: [],
    selectedPost: {
      title: 'Select a Post',
      content: 'Once you select a post on the left, the content will display here.'
    }
}  

IMPORTANT In this example I gave ‘title’ and ‘content’ a value only because I wanted something to show in our blog post section by default; it would have been perfectly fine to just write the following:

data: {
    posts: [],
    selectedPost: {}
}

And when our selectedPost property is updated, we see the details in the view.

<article class="blogPost">
    <header>
        <h1 class="blogPost__title">
            {{selectedPost.title}}
        </h1>
    </header>
    <div class="blogPost__body" v-html="selectedPost.content">

    </div>
</article>

The v-html Directive

The selectedPost.content contains html markup, so we need to use the v-html directive. Try removing that directive and just use {{selectedPost.content}} to see what would happen.

<article class="blogPost">
    <header>
        <h1 class="blogPost__title">
            {{selectedPost.title}}
        </h1>
    </header>
    <div class="blogPost__body">
        {{selectedPost.content}}
    </div>
</article>

Challenges

After you have read through the code and feel you have a good grasp on what’s going on, try the following challenges:

  1. Fetch posts from a different blog on WordPress.com.
  2. Visit the API documentation and see if you can create a list of the blog’s categories.
  3. Add a link to each of those categories that when clicked will request posts from that category.
  4. Render a list of titles for each of those requested posts like we have in our original app, and wire up a request for any of those particular posts when their title is clicked.