Creating The Homepage – VueJS WordPress Theme

in WordPress Theme

With the project setup, we can now focus on building the pages we need for the WordPress theme.

First we're going to start off with the homepage, throughout this project we'll just focus on building the standard WordPress site, this means the homepage will simply list the latest 10 posts from your blog. These 10 blog posts will consist of the title, an excerpt of the content and a read more link to the main post.

We'll also need to add some sort of pagination at the bottom of the page so we can navigate to the next 10 posts in the blog.

Before we get started on building the homepage we need to split up the page into different components for this example we're going to keep this as simple as possible and will create components for the header, content area and footer.

In the previous tutorial, we built the main App.vue file which will insert the header and footer making the content component easier to handle as we just need to add the content for that page.

A VueJS single file component is split up into 3 sections: template, script and style.

The template is where you put all the HTML used by the component.

The script is where you'll place all the JavaScript code used by this component, here is where you'll have your data variables and the HTTP requests to populate the component.

Template Section

The template section needs to have one root element, therefore, we can just create a div with an ID of the page (homepage).

Then we're going to have a title for the list of posts, a search form and another VueJS component to display the list of posts. The reason we're going to create a list post component is so we can reuse this on pages such as the search results page and category pages.

We use the VueJS builtin functionality of props to pass in the posts variable into the list-posts component.

<template>
    <div id="homepage">
        <h2 class="title is-2">Latest Posts</h2>

        <search></search>

        <list-posts v-bind:posts="posts"></list-posts>
    </div>
</template>

Script Section

The script section is where we will do all the JavaScript work for the application, first, we need to import the dependencies for this component, this includes Axios, the list posts component and the search form component.

import axios from 'axios'
import ListPosts from '../global/ListPosts.vue'
import Search from '../forms/Search.vue'

Then we need to define the default data for the page, this will consist of a page title we can use to change the document title tag and an empty posts array we will populate from the WordPress API.

data () {
  return {
    title: 'VueJS WordPress Theme',
    posts: []
  }
}

When the component is created from the Vue router we're going to then fetch the posts from the API and change the document title to the homepage title. We can do this by creating the default created() function.

created () {
    this.getPosts()
    document.title = this.title
  },

We now need to create the getPosts method, within your VueJS component you can use the methods property to define all your methods.

methods: {
    getPosts () {
    }
  },

The getPosts method is what we'll use to get the list of posts using the Axios library. We need to call the API endpoint /posts which will return the latest 10 posts from the API. The response of this call will then be populated into the posts data variable.

methods: {
    getPosts () {
      axios.get(process.env.API_URL + '/wp-json/wp/v2/posts')
      .then(response => {
        this.posts = response.data
      })
      .catch(e => {
        console.log(e)
      })
    }
  },

Finally, you need to define which components are being imported.

components: {
    'list-posts': ListPosts,
    Search
  }

Full Component

Below is the full code for the Homepage component.

<template>
    <div id="homepage">
        <h2 class="title is-2">Latest Posts</h2>

        <search></search>

        <list-posts v-bind:posts="posts"></list-posts>
    </div>
</template>

<script>
import axios from 'axios'
import ListPosts from '../global/ListPosts.vue'
import Search from '../forms/Search.vue'

export default {
  name: 'Homepage',
  data () {
    return {
      title: 'VueJS WordPress Theme',
      posts: []
    }
  },

  created () {
    this.getPosts()
    document.title = this.title
  },

  methods: {
    getPosts () {
      axios.get(process.env.API_URL + '/wp-json/wp/v2/posts')
      .then(response => {
        this.posts = response.data
      })
      .catch(e => {
        console.log(e)
      })
    }
  },

  components: {
    'list-posts': ListPosts,
    Search
  }
}
</script>

Create List Posts Component

We're going to create a global list post component and store this inside the folder /src/components/global/ListPosts.vue.

The template section will loop through all the posts and pass them into a post-preview component, this component is going to display a single post using the excerpt as the content.

<template>
    <div class="list-posts">
        <post-preview v-for="post in posts" :key="post.id" v-bind:post="post"></post-preview>
    </div>
</template>

The script tag will just need to import the post preview component.

import PostPreview from './PreviewPost.vue'

And expect a posts prop.

props: ['posts']

Here is the full code to go into the list posts component.

<template>
    <div class="list-posts">
        <post-preview v-for="post in posts" :key="post.id" v-bind:post="post"></post-preview>
    </div>
</template>

<script>
import PostPreview from './PreviewPost.vue'

export default{
  props: ['posts'],

  components: {
    'post-preview': PostPreview
  }
}
</script>

Preview Post Component

As the list post component includes a preview post component so we need to create this in our theme.

This will be stored inside /src/components/global/PreviewPost.vue

The script section for the component is very simple it will just expect a post prop.

export default{
  props: ['post']
}

The template section is going to do all the work for this component, it starts like every other Vue component with a single root element. Then as this is just going to preview the post where you click through to the entire post the next element will be an anchor tag to the post, for this we use a router-link we make this display a post by using our named route post passes in params of postSlug.

<router-link :to="{ name:'post', params: {postSlug: post.slug} }"><router-link>

The next element will display the post title from the prop.

<h2 class="post-title title is-3">{{ post.title.rendered}}</h2>

Next, we display the excerpt using the data from the prop.

<p class="post-excerpt">{{ post.excerpt.rendered }}</p>

Next we can add a link to invite the visitor to read more.

<p><router-link :to="{ name:'post', params: {id: post.id, postSlug: post.slug} }" class="read-more">Read More</router-link></p>

Below is the entire code for the preview post component.

<template>
    <div class="preview-post">
        <router-link :to="{ name:'post', params: {postSlug: post.slug} }">
            <h2 class="post-title title is-3">{{ post.title.rendered}}</h2>
            <p class="post-excerpt">{{ post.excerpt.rendered }}</p>
            <p><router-link :to="{ name:'post', params: {id: post.id, postSlug: post.slug} }" class="read-more">Read More</router-link></p>
        </router-link>
    </div>
</template>

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

If you have webpack running while creating these file it will now of compiled your files and you'll be able to see your theme working displaying the latest 10 posts of your blog.

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