Giter Site home page Giter Site logo

Comments (13)

jacobmishkin avatar jacobmishkin commented on May 8, 2024 4

There is a couple of other things you need to do. You need to make sure the callback function inside the register_rest_route is set, to: get_rest_your_cpt. you also need to write your callback function, scroll down, in the api-route page and add your callback function to the list. then in the functions rest_get_content, and get_content_by_slug in the $type array add your cpt to the array. This corresponds to your callback function. Lastly, when you are linking your cpt from the homepage to it's own page you want to change the Link props to:

             <Link
              key={index}
              as={`/your_cpt_name_here/${your_returned_variable_here.slug}`}
              href={`/post?slug=${your_returned_variable_here.slug}&apiRoute=your_cpt_name_here`}
             ></Link

if you keep Post.js the same, the above link will display your cpt in Post.js.

I hope this helps, if you have more questions, please feel free to ask.

from headless-wp-starter.

Triphys avatar Triphys commented on May 8, 2024 1

Hey! Just wanted to get back to you and tell you that something else was acting up somehow. After I followed your steps with deconstructing and this.props it didnt work at first until I restarted Yarn.. Et voila, everything worked. Very strange but now it works fine :)
Thank you very much!

from headless-wp-starter.

jacobmishkin avatar jacobmishkin commented on May 8, 2024

Just curious did you modify your api-routes.php file?

from headless-wp-starter.

justinledelson avatar justinledelson commented on May 8, 2024

@jacobmishkin I copied the register_rest_route function for posts and replaced "post" with my custom post type slug. Is there anything else I need to do?

from headless-wp-starter.

Triphys avatar Triphys commented on May 8, 2024

p Post.js the same, the above link will display your cpt in Post.js.

I hope this helps, if you have more questions, please feel free to ask.

I got this working perfectly thanks to your info <3
Just a small question... I would like my CPT to be rendered in another "template" called postService.js instead of post.js but I can't seem to get it working. Where do I change which file renders the posts?

from headless-wp-starter.

Triphys avatar Triphys commented on May 8, 2024

p Post.js the same, the above link will display your cpt in Post.js.
I hope this helps, if you have more questions, please feel free to ask.

I got this working perfectly thanks to your info <3
Just a small question... I would like my CPT to be rendered in another "template" called postService.js instead of post.js but I can't seem to get it working. Where do I change which file renders the posts?

@jacobmishkin I actually got this to work since I found the guide on your blog :)
But my only problem left now is that when click my link on index.js

const services = this.props.services.map((services, index) => {
	return (
		<ul key={index}>
			<li>
				<Link
					as={`/services/${services.slug}`}
					href={`/post?slug=${services.slug}&apiRoute=services`}
				>
					<a>{services.title.rendered}</a>
				</Link>
			</li>
		</ul>
	);
});

I come to http://localhost:3000/services/tjanst-4 which renders fine, but if I go for that address immediately I get an 404 cannot be found :/
Any ideas?

from headless-wp-starter.

jacobmishkin avatar jacobmishkin commented on May 8, 2024

Hey man, did you get this working? I take it your having issues if you directly enter that URL into the browser, but on the home page with a button it works?

from headless-wp-starter.

jacobmishkin avatar jacobmishkin commented on May 8, 2024

I'm glad you found my blog post to be helpful. Thanks!!

from headless-wp-starter.

Triphys avatar Triphys commented on May 8, 2024

Hey man, did you get this working? I take it your having issues if you directly enter that URL into the browser, but on the home page with a button it works?

Hey @jacobmishkin ! Unfortunately not, but I can't for the love of my life understand why haha.
I just did a clean setup of postlight now and followed your guide from scratch creating a movies.js /page and a Movies.js component in /components. I wasn't totally sure how to link to the actual post in index.js but I get it to list my "movies".

Here's my index.js

import Layout from "../components/Layout.js";
import React, { Component } from "react";
import fetch from "isomorphic-unfetch";
import Link from "next/link";
import PageWrapper from "../components/PageWrapper.js";
import Menu from "../components/Menu.js";
import Movies from "../components/Movies.js";
import { Config } from "../config.js";

const headerImageStyle = {
    marginTop: 50,
    marginBottom: 50
};

class Index extends Component {
    static async getInitialProps(context) {
        const pageRes = await fetch(
            `${Config.apiUrl}/wp-json/postlight/v1/page?slug=welcome`
        );
        const page = await pageRes.json();
        const postsRes = await fetch(
            `${Config.apiUrl}/wp-json/wp/v2/posts?_embed`
        );
        const posts = await postsRes.json();
        const moviesRes = await fetch(
            `${Config.apiUrl}/wp-json/wp/v2/movies?_embed`
        );
        const movies = await moviesRes.json();
        const pagesRes = await fetch(
            `${Config.apiUrl}/wp-json/wp/v2/pages?_embed`
        );
        const pages = await pagesRes.json();
        return { page, posts, movies, pages };
    }

    render() {
        const posts = this.props.posts.map((post, index) => {
            return (
                <ul key={index}>
                    <li>
                        <Link
                            as={`/post/${post.slug}`}
                            href={`/post?slug=${post.slug}&apiRoute=post`}
                        >
                            <a>{post.title.rendered}</a>
                        </Link>
                    </li>
                </ul>
            );
        });
        const movies = this.props.movies.map((post, index) => {
            return (
                <ul key={index}>
                    <li>
                        <Link
                            as={`/movies/${post.slug}`}
                            href={`/post?slug=${post.slug}&apiRoute=movies`}
                        >
                            <a>{post.title.rendered}</a>
                        </Link>
                    </li>
                </ul>
            );
        });
        const pages = this.props.pages.map((page, index) => {
            return (
                <ul key={index}>
                    <li>
                        <Link
                            as={`/page/${page.slug}`}
                            href={`/post?slug=${page.slug}&apiRoute=page`}
                        >
                            <a>{page.title.rendered}</a>
                        </Link>
                    </li>
                </ul>
            );
        });
        return (
            <Layout>
                <Menu menu={this.props.headerMenu} />
                <img
                    src="/static/images/wordpress-plus-react-header.png"
                    width="815"
                    style={headerImageStyle}
                />
                <h1>{this.props.page.title.rendered}</h1>
                <div
                    dangerouslySetInnerHTML={{
                        __html: this.props.page.content.rendered
                    }}
                />
                <h2>Movies</h2>
                {movies}
                <h2>Posts</h2>
                {posts}
                <h2>Pages</h2>
                {pages}
            </Layout>
        );
    }
}

export default PageWrapper(Index);

And here's a gif of the result. It won't render the post in movies.js but it looks like default post.js instead. And when reloading the browser or going straight for the url it gives my a 404. Seems like some kind of routing problem or? Can't figure it out :/

screenflow

from headless-wp-starter.

jacobmishkin avatar jacobmishkin commented on May 8, 2024

No Worries. Is this issue going on, on all pages outside of index.js? or just the movies.js page? In your Layout component on the movies page, did you destructure and spread the props in the layout component? like this:

<Layout {...this.props}>

This might help, if not please let me know.

from headless-wp-starter.

jacobmishkin avatar jacobmishkin commented on May 8, 2024

Take a look at your routes, your movies Page may need to be lower case. Change the name of the Page component to movies.js not Movies.js. The component in the components folder can be uppercase.

This is an express issue. I'd double check the routes in server.js make sure they match the page file in pages. ie. Movies.js vs movies.js ect.

from headless-wp-starter.

Triphys avatar Triphys commented on May 8, 2024

Hello again @jacobmishkin and thanks for the help so far :)
I somehow managed to get it working for the "movies" example when I switched to this.props. But strange thing is that when Im trying to replicate it for another post type called "tjanster" it doesnt work. Even though I'm using exactly the same settings.

What happens now is that I can list all posts from both "tjanster" and "movies" on the frontpage, I can also visit any post and they render in the correct template (movies.js and tjanster.js). But if I'm visiting a tjanster-post (localhost/tjanster/post-1) and then reload the page or go directly to that page I get a 404 not found like before. But this does not happen with the movies posts anymore (localhost/movies/movie-1), they reload just fine.

This is my current folder structure:
screenshot 2018-11-12 at 17 24 02

And this is my server.js:

const express = require("express");
const next = require("next");

const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

app
    .prepare()
    .then(() => {
        const server = express();

        server.get("/post/:slug", (req, res) => {
            const actualPage = "/post";
            const queryParams = { slug: req.params.slug, apiRoute: "post" };
            app.render(req, res, actualPage, queryParams);
        });

        server.get("/movies/:slug", (req, res) => {
            const actualPage = "/movies";
            const queryParams = { slug: req.params.slug, apiRoute: "movies" };
            app.render(req, res, actualPage, queryParams);
        });

        server.get("/tjanster/:slug", (req, res) => {
            const actualPage = "/tjanster";
            const queryParams = { slug: req.params.slug, apiRoute: "tjanster" };
            app.render(req, res, actualPage, queryParams);
        });

        server.get("/page/:slug", (req, res) => {
            const actualPage = "/post";
            const queryParams = { slug: req.params.slug, apiRoute: "page" };
            app.render(req, res, actualPage, queryParams);
        });

        server.get("/category/:slug", (req, res) => {
            const actualPage = "/category";
            const queryParams = { slug: req.params.slug };
            app.render(req, res, actualPage, queryParams);
        });

        server.get("/_preview/:id/:wpnonce", (req, res) => {
            const actualPage = "/preview";
            const queryParams = { id: req.params.id, wpnonce: req.params.wpnonce };
            app.render(req, res, actualPage, queryParams);
        });

        server.get("*", (req, res) => {
            return handle(req, res);
        });

        server.listen(3000, err => {
            if (err) throw err;
            console.log("> Ready on http://localhost:3000");
        });
    })
    .catch(ex => {
        console.error(ex.stack);
        process.exit(1);
    });

This is my index.js

import Layout from "../components/Layout.js";
import React, { Component } from "react";
import fetch from "isomorphic-unfetch";
import Link from "next/link";
import PageWrapper from "../components/PageWrapper.js";
import Menu from "../components/Menu.js";
import { Config } from "../config.js";

class Index extends Component {
	static async getInitialProps(context) {
		
		const pageRes = await fetch(
			`${Config.apiUrl}/wp-json/postlight/v1/page?slug=landingpage`
		);
		const page = await pageRes.json();
				
		const postsRes = await fetch(
			`${Config.apiUrl}/wp-json/wp/v2/posts?_embed`
		);
		const posts = await postsRes.json();
				
		const moviesRes = await fetch(
			`${Config.apiUrl}/wp-json/wp/v2/movies?_embed`
		);
		const movies = await moviesRes.json();

		const tjansterRes = await fetch(
			`${Config.apiUrl}/wp-json/wp/v2/tjanster?_embed`
		);
		const tjanster = await tjansterRes.json();
				
		const pagesRes = await fetch(
			`${Config.apiUrl}/wp-json/wp/v2/pages?_embed`
		);
		const pages = await pagesRes.json();
		
		return { page, posts, movies, pages, tjanster };
		
	}

	render() {
		
		const movies = this.props.movies.map((post, index) => {
			return (
				<ul key={index}>
					<li>
						<Link
							as={`/movies/${post.slug}`}
							href={`/movies?slug=${post.slug}&apiRoute=movies`}
						>
							<a>{post.title.rendered}</a>
						</Link>
					</li>
				</ul>
			);
		});

		const tjanster = this.props.tjanster.map((post, index) => {
			return (
				<ul key={index}>
					<li>
						<Link
							as={`/tjanster/${post.slug}`}
							href={`/tjanster?slug=${post.slug}&apiRoute=tjanster`}
						>
							<a>{post.title.rendered}</a>
						</Link>
					</li>
				</ul>
			);
		});

		return (
			<Layout>
				<Menu menu={this.props.headerMenu} />						
				{movies}
				{tjanster}
			</Layout>
		);
	}
}

export default PageWrapper(Index);

This is my pages/movies.js:

import Layout from "../components/Layout.js";
import React, { Component } from "react";
import fetch from "isomorphic-unfetch";
import Error from "next/error";
import PageWrapper from "../components/PageWrapper.js";
import Menu from "../components/Menu.js";
import { Config } from "../config.js";

class Movies extends Component {
    static async getInitialProps(context) {
        const { slug, apiRoute } = context.query;
        const res = await fetch(
            `${Config.apiUrl}/wp-json/postlight/v1/${apiRoute}?slug=${slug}`
        );
        const movies = await res.json();
        return { movies };
    }

    render() {
        if (!this.props.movies.title) return <Error statusCode={404} />;

        return (
            <Layout>
                <Menu menu={this.props.headerMenu} />
                <section className="page__container">
                    <h2>Movies</h2>
                    <h1>{this.props.movies.title.rendered}</h1>
                </section>
            </Layout>
        );
    }
}

export default PageWrapper(Movies);

And my tjanster.js:

import Layout from "../components/Layout.js";
import React, { Component } from "react";
import fetch from "isomorphic-unfetch";
import Error from "next/error";
import PageWrapper from "../components/PageWrapper.js";
import Menu from "../components/Menu.js";
import { Config } from "../config.js";

class Tjanster extends Component {
    static async getInitialProps(context) {
        const { slug, apiRoute } = context.query;
        const res = await fetch(
            `${Config.apiUrl}/wp-json/postlight/v1/${apiRoute}?slug=${slug}`
        );
        const tjanster = await res.json();
        return { tjanster };
    }

    render() {
        if (!this.props.tjanster.title) return <Error statusCode={404} />;

        return (
            <Layout>
                <Menu menu={this.props.headerMenu} />
                <section className="page__container">
                    <h2>Tjanster</h2>
                    <h1>{this.props.tjanster.title.rendered}</h1>
                </section>
            </Layout>
        );
    }
}

export default PageWrapper(Tjanster);

Seems very strange :/

from headless-wp-starter.

jacobmishkin avatar jacobmishkin commented on May 8, 2024

@Triphys Awesome! Glad I could help.

from headless-wp-starter.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.