Create The Post Page – VueJS WordPress Theme

in WordPress Theme

In the previous tutorial, we created the Homepage for the VueJS theme, with the Homepage showing a list of posts with a link to the post page we can now create the post page.

With the post route setup in a previous tutorial about setting up WordPress routes.

{
  name: 'post',
  path: '/:postSlug',
  component: Single
}

When you go to a url of /post-slug Vue router will load in the component Single, which is our Post.vue component.

Post Page

The Post component will be loaded when you navigate to the URL, for this we need to use the WordPress API to fetch the post with the slug in the router. If the post is found we can store this inside the post variable to send through to the single-post component. If the post isn't found then we need to redirect the visitor to the 404 Not found page.

Like the other Vue components, we can start with the template tag that will hold all the HTML for the component. This Post page is very simple we just need to show the single-post component and pass in the post variable that is populated with the post data for the current slug.

<template>
    <single-post v-bind:post="post"></single-post>
</template>

Inside the script tag is where we have all the JavaScript code for the component. To start with we need to import the axios library to make our API call and the SinglePost component.

import axios from 'axios'
import SinglePost from '../global/SinglePost.vue'

The data needed inside this component is title and post array. The title is what we're going to use to name the page in the title tag. The post array is used to store all the data for the current post.

data () {
  return {
    title: '',
    post: []
  }
}

There is going to be a created function that will get the current post data.

created () {
  this.getPost()
}

There is only one method on this component and it will make a call to the WordPress API to get the data and store this in the post data variable.

methods: {
    getPost () {
      var path = this.$route.path
      axios.get(process.env.API_URL + '/wp-json/wp/v2/posts/?slug=' + path.replace(/^\/|\/$/g, ''))
      .then(response => {
        this.post = response.data[0]

        if (this.post === undefined) {
          this.$router.push({name: 'NotFound'})
        }
        document.title = this.post.title.rendered
      })
      .catch(e => {
        console.log(e)
      })
    }
  },

Then finally we need to define the single-post tag in the component list.

components: {
    'single-post': SinglePost
  }

Full Post.vue Component

Below is the full code for the Post.vue component.

<template>
    <single-post v-bind:post="post"></single-post>
</template>

<script>
import axios from 'axios'
import SinglePost from '../global/SinglePost.vue'

export default{
  name: 'Single',
  data () {
    return {
      title: '',
      post: []
    }
  },

  created () {
    this.getPost()
  },

  methods: {
    getPost () {
      var path = this.$route.path
      axios.get(process.env.API_URL + '/wp-json/wp/v2/posts/?slug=' + path.replace(/^\/|\/$/g, ''))
      .then(response => {
        this.post = response.data[0]

        if (this.post === undefined) {
          this.$router.push({name: 'NotFound'})
        }
        document.title = this.post.title.rendered
      })
      .catch(e => {
        console.log(e)
      })
    }
  },

  components: {
    'single-post': SinglePost
  }
}
</script>

Single Post Component

With the Post.vue component created and calling single post component we can now create the Single post component.

This component is very simple and only really has the HTML to display the content. From the Post component, we're passing in the data using props so we need to make sure that this is accepted within our single post component.

<script>
export default{
  props: ['post']
}
</script>

The important information we can access from the post information in this example is post.title and post.rendered, obviously with WordPress there's lots more information we could get such as post date and post category but we'll keep it simple for this example and expand on this later.

When you access the content that can be displayed to the front-end it returns with a .rendered property. This is what we need to use to output within our VueJS component.

To display the post title we need to use the following code.

<h1 class="title is-1">
  {{ post.title.rendered }}
</h1>

As for the post content it will return HTML so we need to display this in a different way by using the directive v-html.

<section class="content-container" v-html="post.content.rendered">
</section>

Below is the full code used for the single post component.

<template>
    <div class="post">
        <section class="hero">
            <div class="hero-body">
                <div class="container">
                    <h1 class="title is-1">
                        {{ post.title.rendered }}
                    </h1>
                </div>
            </div>
        </section>

        <div class="content-area">
            <section class="content-container" v-html="post.content.rendered">
            </section>
        </div>
    </div>
</template>

<script>
export default{
  props: ['post']
}
</script>

Next up we can create the static Page component.

Upgrade to access all content on Paulund

Members unlock all tutorials and snippets

Access to all downloadable content

Access to code examples before others

Sign Up Now

Already a member? Login here

Subscribe To Newsletter

Get weekly updates to your email