EvanAgee / vuejs-wordpress-theme-starter

A WordPress theme with the guts ripped out and replaced with Vue.
https://vuewp.com/
1.6k stars 281 forks source link

Correct way to get single post/page from API? #19

Closed smilingpeanut closed 6 years ago

smilingpeanut commented 6 years ago

Hi there,

I've got this theme installed and so far, most things are making sense. What I can't figure out is how to use the bundled API method getPage() to pass the content to the component. I'd love to see a full example of how this is accomplished. So far, what I've been trying are different combinations of this (screenshot):

https://cloudup.com/cokkIKOWUlk

Any help would be very much appreciated.

samizarraa commented 6 years ago

I think you can make new method getPost() or add post_type to method.

smilingpeanut commented 6 years ago

@samizarraa There is already a getPost() method. What I'm trying to do is use it in a component.

EvanAgee commented 6 years ago

Hey @smilingpeanut and anyone else who's struggled with this. I'm either going to either write up an explanation, commit some documentation to the project OR record a video explaining this. I'll respond here once I do, sorry for the delay!

EvanAgee commented 6 years ago

The approach I would take would be as follows.

  1. Set your component up to display properties of the page object
  2. Set up a new action on the page module called getPage, ignore the one in the api file. Make sure your action toggles the module's loaded state to false. In that action commit that resulting page object to the state and toggle the loaded state to true.
  3. On beforeMount dispatch getPage with the appropriate page ID (from params)
  4. Use the loaded state to show/hide content on your component

Hopefully that helps!

smilingpeanut commented 6 years ago

Hi @EvanAgee! Thanks for the response. I apologize, but I'm not able to make any headway. I'm still learning Vue so the instructions you've provided are basically a foreign language. Would you be so kind as to illustrate this with a skeleton component? I realize this is a big ask, so I understand if you're not able to.

Cheers, Chris

EvanAgee commented 6 years ago

Sure thing @smilingpeanut let me see what I can do!

sazr commented 6 years ago

@EvanAgee great boilerplate theme you've made! :)

I second @smilingpeanut, it would be awesome to see how to put together the post/page displaying :)

sazr commented 6 years ago

@EvanAgee I've kindof managed to put together your implementation instructions above. But I believe theres more I need to implement? And some I need to change?

src/router/index.js:

// Components
import Home from '../components/Home'
import Page from '../components/Page'

Vue.use(Router)

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home,
      // props: { pageContentID: 383 }
    },
    {
      path: '/page/:pageId',
      component: Page,
      props: true
    }
  ],
  ...

src/store/modules/page.js:

const getters = {
  ...

  // Add the following getters
  getPage: state => (id) => {
    let page = state.all.filter(page => page.id === id)
    return !_.isNull(_.first(page)) ? _.first(page) : false
  },
  pageLoaded: state => (id) => {
    let page = state.all.filter(page => page.id === id)
    return !_.isNull(_.first(page));
  },
}

// actions
const actions = {
  ...

  // Add the following action: I dont think this is correct? 
  getPage ({ id, commit }) {
    commit(types.PAGES_LOADED, false) // you mentioned to set this to false?

    api.getPage(id, page => {
      commit(types.STORE_FETCHED_PAGES, { page })
      commit(types.PAGES_LOADED, true) 
      commit(types.INCREMENT_LOADING_PROGRESS)
    })
  }
}

src/components/Page.vue:

<template>
    <b-container class="bv-example-row" v-if="pageLoaded">
        <h1>{{ page.title.rendered }}</h1>

        <b-row>
            <b-col>
                {{ page.content.rendered }}
            </b-col>
        </b-row>
    </b-container>
    <b-container class="bv-example-row" v-else>Loading...</b-container>
</template>

<script>
import { mapGetters } from 'vuex'

export default {

    props: ['pageId'],

    computed: {
        ...mapGetters({
          getPage: 'getPage', // Do I need to bring this in? 
          pageLoaded: 'pageLoaded',
          page: 'getPage'
        }),
    },

    beforeMount() {
        this.$store.dispatch('getPage', this.pageId);
    }
}
</script>

<style lang="scss">

</style>
OriginalDOMDada commented 6 years ago

having trouble with this any update?

Berckan commented 6 years ago

I am having problems with this as well, I can't manage to get a post entry to show, the page only show the header and footer, but not the actual post content. Any ideas?

EvanAgee commented 6 years ago

If you're still having issues with this you'll be glad to see the next update. Stay tuned!

tomhrtly commented 5 years ago

I'm still having the same problem as @Berckan, the post content does not show and when clicking on a link to a post on the homepage, it does not load through Vue like the pages do, it reloads the page like a normal site.

No errors in the console. Permalink settings are set to "Month and name", problem still persists on either option.

Any fixes @EvanAgee?

giekaton commented 5 years ago

I'm in a similar situation also. Going through the github issues, looking for a way to load page content. No luck yet.

I can load the default home content, but when I click on any of the custom created wp pages (or access them by direct url), the content is always empty, just header and footer visible.

EvanAgee commented 5 years ago

@tomhrtly and @giekaton have you updated to the latest version of the repo yet? I had to make some adjustments to routing to get post content to load.

giekaton commented 5 years ago

@EvanAgee thanks for a quick reply.

Yes, I'm using the latest version, and I have added my local path (localhost/project_path/) to the router's index.js and to settings.js. I'm now able to load the default home page with header, footer, your greeting message in home page and pages widget. When I click on any page link in a widget, or try to access it directly, the content of the page (that I created through the wp editor) is not showing.

giekaton commented 5 years ago

I'm not sure if the page content should be loaded by default, or do I need to add some custom code to load pages? Where can I find more info about this?

giekaton commented 5 years ago

Ok, finally got it working.

Pages are loaded automatically through a Page.vue component. But the Page.vue component itself was not loading. To fix this I needed to update the path also for Pages in router's index.js

{
  path: "/project_path/:pageSlug",
  name: "Page",
  component: Page
}
giekaton commented 5 years ago

Btw, I think these are important things that can be added to the quickstart docs:

  1. After 'npm run watch' where to find the running app? Answer: It's in the default wp location, but this was not explained in docs. Found the answer in https://github.com/EvanAgee/vuejs-wordpress-theme-starter/issues/7

  2. Why the initial page content doesn't load? Because the paths need to be updated in /router/index.js and in settings.js. The question was raised here but also saw it in other issues.

EvanAgee commented 5 years ago

I like the recommendation for updating the docs @giekaton and it's definitely inspired me to revisit them and see what can be clarified.

Tes3awy commented 5 years ago

Ok, finally got it working.

Pages are loaded automatically through a Page.vue component. But the Page.vue component itself was not loading. To fix this I needed to update the path also for Pages in router's index.js

{
  path: "/project_path/:pageSlug",
  name: "Page",
  component: Page
}

What if I added project_path to the base in the router object? I am still having this issue of being unable to load neither page or post. Can you help me please with this issue?

I am always getting these two errors in the console [Vue warn]: Error in created hook: "TypeError: Cannot read property 'get' of undefined", TypeError: Cannot read property 'get' of undefined