Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't have pages with children render correctly: routes: { page: ':link', #19

Open
Kainkainkain opened this issue Aug 7, 2019 · 11 comments

Comments

@Kainkainkain
Copy link

    routes: {
      page: ':link',
      post: '/media/:year/:month/:slug', //adds route for "post" post type (Optional)
      post_tag: '/tag/:slug' // adds route for "post_tag" post type (Optional)
    }

Doesn't work.
routes: { page: ':link_raw', }
is close - but the / character comes out as URL decoded %2f.
E.g. all the links are:
mysite.com/toppage%2fsecondlevel%2fthirdlevel

So can only have /pages/:slug which is not SEO or structured (especially for 3-4 level deep websites).

Goal would be able to replicate wordpress page structure

@Kainkainkain
Copy link
Author

Kainkainkain commented Aug 16, 2019

Just me that wants to render pages and child pages with correct routes matching WordPress permalinks so WordPress users can use the CMS headless without restriction?

I'm going to read up on how this add node thing works and see if I can split up the WordPress link attribute that's delivers things like '/sections/about-us/corporate-info/annual-report/' and see if I can make routes for each one dynamically.

@Kainkainkain
Copy link
Author

I feel like this is the answer but I don't understand the documentations context, like where I would put my modified version of the code- in the plugins array?
https://gridsome.org/docs/routing/#routing-for-custom-data

@Kainkainkain
Copy link
Author

Kainkainkain commented Aug 19, 2019

I have been able to successfully build page and there routes without the wordpress starter,
So now I can build pages and routes, but I have to duplicate all the other benefits the the starter offered. 'link' does work, so the worpdress starter code (look complex when I looked it up in node_modules/@gridsome/source-wordpress).
If I was a better coder maybe I could make a pull to improve this starter but I can't, it will be faster for me to build from basic gridsome. Unfortunate I can't use this starter.

Check it:

//gridesome.server.js
const axios = require('axios')

module.exports = function (api) {
api.createManagedPages(async ({ createPage }) => {
const { data } = await axios.get('https://www.eg.com/wp-json/wp/v2/pages')

data.forEach(item => {      
  createPage({
    path: '/'+item.link,
    component: './src/layouts/Page.vue',
    context: {
      page: item,
      // title: item.title,
      // content: item.content
    }
  })
})

})

@daviddarke
Copy link

Hi there @Kainkainkain , I got this working fine with:

module.exports = {
  siteName: 'Gridsome',
  siteDescription: 'A WordPress starter for Gridsome',
  plugins: [
    {
      use: '@gridsome/source-wordpress',
      options: {
        baseUrl: 'https://www.url.dev', // required
        typeName: 'WordPress', // GraphQL schema name (Optional)
        perPage: 100, // How many posts to load from server per request (Optional)
        concurrent: 10, // How many requests to run simultaneously (Optional)
        routes: {
          post: '/blog/:slug', //adds route for "post" post type (Optional)
          page: '/:slug',
        }
      }
    }
  ]
}

So page simply set to:

page: '/:slug',

The main difference here is the homepage is in Gridsome, other pages aren't.

@Kainkainkain
Copy link
Author

@daviddarke and did this handle page parents and page depth? e.g.
like
/sections/about-us/index.html
/sections/about-us/corporate-info/index.html
/sections/about-us/corporate-info/annual-report/index.html

@daviddarke
Copy link

daviddarke commented Aug 22, 2019

@Kainkainkain That is a very point. I see from your initial post that was a goal. 🤔

@hjvedvik Are you looking into hierarchical post types? I assume to keep the WP-API fields clean and intact, it would make sense to add a new 'hierarchy-link' (or whatever) field to the GraphQL store. This could be as simple as the permalink with the base URL removed right? I would love to know your thoughts on this.

@ramiroazar
Copy link

I'm hoping to achieve this as well.

It would be nice to have paths reflect the URL structure already defined in WordPress where possible.

I think your interpretation is correct, @daviddarke, those would seem to be the options.

  1. Add field to GraphQL
  2. Add field to WordPress REST API

In any case, the new field would have a value equivalent to link, but without the hostname.

I have attempted achieving the first option through Gridsome plugins and transformers, but haven't had any success.

Due to my lack of experience with Gridsome, currently the second option is looking more viable.

However, it would still be good to know if this can indeed be achieved in Gridsome.

@ramiroazar
Copy link

I have since attempted implementing this through WordPress, so just sharing my findings.

A link_relative field can be added to responses using register_rest_field.

/parent-page/child-page/

Node fields can be used as path parameters.

/:link_relative

Path parameters are slugified by default.

/parent-page-child-page/

Original values can be used by adding a _raw suffix.

/:link_relative_raw

Special characters in original values seem to be encoded.

/%2Fparent-page%2Fchild-page%2F/

Unfortunately, modifying WordPress REST API responses gets pretty close, but does not seem to be a viable workaround.

Ideally, template paths could be defined programmatically when using source plugins, similar to createPage.

Alternatively, it would be good to know how to add a field to GraphQL when using source plugins.

@Kainkainkain
Copy link
Author

I should have shared the solution i worked out:
data.allPages.edges.forEach(({ node }) => {

      createPage({
        path: `${node.link}`, 
        component: './src/components/Page.vue',
        context: {          
          id: node.id, 
          slug: node.name,
          title: node.title,
          content: node.content,
          parentid: node.parentid,
          link: node.link, 
          byline: node.acf.byline, 
          page_type: node.acf.page_type, 
          acf: node.acf
        }
      })

    }

  })

@Rocketpilot
Copy link

Hi @ramiroazar I attempted to follow the discussion in the linked feature request and I cannot work out how to apply it to the situation @Kainkainkain described in the original post in this thread. It seems that it is possible to obtain the parent slug?

I have the following code in my Gridsome.config.js templates block:

WordPressPage: '/:parent/:slug',

But on Gridsome build that outputs

\0\page_with_id_22
\22\subpage_of_page_with_id_22

Which is if you squint nearly what I need, but doesn't quite get there.

Any suggestions?

@ramiroazar
Copy link

Instead of using a string with parameters in the template path option, you can use a function, which allows you to get the full path.

WordPressPage: (node) => {
  return new URL(node.link).pathname
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants