DEV Community

Cover image for Wordpress with React and Apollo
dillan teagle
dillan teagle

Posted on • Edited on

3 1

Wordpress with React and Apollo

Ive decided to tryout React with GraphQL, Apollo, and Wordpress.

Repo: https://github.com/teaglebuilt/teaglebuilt.com

index.js


import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { ApolloClient } from 'apollo-boost';
import { createHttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { BrowserRouter } from 'react-router-dom';
import { ApolloProvider } from 'react-apollo';
import Config from './config';


const client = new ApolloClient({
    link: createHttpLink({
      uri: Config.gqlUrl,
    }),
    cache: new InMemoryCache(),
  });


ReactDOM.render(
    <BrowserRouter>
        <ApolloProvider client={client}>
            <App />
        </ApolloProvider>
    </BrowserRouter>,
    document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

App.js

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Home from './components/Home';
import Header from './components/Header';
import Sidebar from './components/Sidebar';
import Page from './components/Page';
import Post from './components/Post';
import Category from './components/Category';
import Tagbar from './components/Tagbar';
import Tag from './components/Tag';
import './styles/index.css';


export default () => (
  <div className="">
    <Header />
    <div className="container w-full flex flex-wrap mx-auto px-2 pt-8 lg:pt-16 mt-16">
    <Sidebar />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route exact path="/page/:slug" component={Page} />
        <Route exact path="/post/:slug" component={Post} />
        <Route exact path="/category/:slug" component={Category} />
        <Route exact path="/tag/:id" component={Tag} />
      </Switch>
    <Tagbar />
    </div>
  </div>
);
Enter fullscreen mode Exit fullscreen mode

Tagbar.js

import React, { Component } from 'react';
import { withApollo } from 'react-apollo';
import { Link } from 'react-router-dom';
import gql from 'graphql-tag';


const TAGS_QUERY = gql`
    query {
        tags {
        edges {
            node {
            id
            link
            name
            slug
            posts {
                edges {
                node {
                    id
                }
                }
            }
            }
        }
        }
    }
`;


class Tagbar extends Component {
    constructor(props){
        super(props);
        this.state = {
            tags: []
        }
    }

    componentDidMount(){
        this.executeTagsQuery();
    }

    executeTagsQuery = async () => {
        const { client } = this.props;
        const result = await client.query({
            query: TAGS_QUERY
        })
        let tags = result.data.tags.edges;
        this.setState({
            tags: tags
        })
    }

    render(){
        const { tags } = this.state;
        return(
            <div className="w-full lg:w-1/5 lg:px-6 text-xl text-gray-800 leading-normal">
            <h1>TagBar</h1>
            <ul>
            {tags.map(tag => (
                <li key={tag.node.slug}>
                    <Link to={`/tag/${tag.node.id}`}>
                        {tag.node.name}
                    </Link>
                </li>
               ))}
            </ul>
        </div>
        )
    }
}

export default withApollo(Tagbar);
Enter fullscreen mode Exit fullscreen mode

So you see here in the graphql query that i could pass the posts for each tag in the map function to the tag component but im not sure if i should do that...meaning render the tag component inside of tagbar.js...

tagbar is a sidebar on the right side of the ui with the list of tags.

tag.js

import React, { Component } from 'react';
import { withApollo } from 'react-apollo';
import { Link } from 'react-router-dom';
import gql from 'graphql-tag';


const TAG_QUERY = gql`
query TagQuery($filter: ID!) {
    tag(id: $filter) {
      slug
      name
      posts {
        edges {
          node {
            content
            slug
            title
          }
        }
      }
    }
  }
`;  



class Tag extends Component {
    constructor(props){
        super(props);
        this.state = {
            tag: {
                name: "",
                posts: []
            }
        }
    }

    componentDidMount(){
        this.executeTagQuery();
    }

    executeTagQuery = async () => {
        const { match, client } = this.props;
        const filter = match.params.id;
        const result = await client.query({
            query: TAG_QUERY,
            variables: { filter }
        })
        const { name } = result.data.tag;
        let posts = result.data.tag.posts.edges;
        posts = posts.map(post => {
            const finalLink = `/tag/${post.node.id}`;
            const modifiedTag = { ...post };
            modifiedTag.node.link = finalLink;
            return modifiedTag;
        })
        const tag = {
          name,
          posts
        }
        this.setState({ tag });
    }

    render(){
        const { tag } = this.state;
        return (
            <div className="w-full lg:w-3/5 p-8 mt-6 lg:mt-0 text-gray-900 leading-normal bg-white border border-gray-400 border-rounded">
              <h4><strong>Posts with Tag:</strong> <em>{tag.name}</em></h4>
              <ul className="py-10 mx-auto">
                {tag.posts.map(post=> (
                  <li key={post.node.slug} className="">
                      <div className="flex my-10">
                        <div className="bg-white w-3/4 m-auto border-1  border-dashed border-gray-100 shadow-md rounded-lg overflow-hidden">
                            <img src="https://via.placeholder.com/400x200" alt="" className="w-full object-cover object-center" />
                            <div className="p-4">
                                <Link to={post.node.link} className="mx-auto f text-gray-900 font-semibold">{post.node.title}</Link>
                                <br/>
                                <span className="text-gray-700">{post.node.content}</span>
                            </div>
                        </div>
                    </div>   
                  </li>
                ))}
              </ul>
          </div>
        )
    }
}

export default withApollo(Tag);
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
highcenburg profile image
Vicente G. Reyes

Hey, community mod here. I highly suggest you use the #help tag to get more traction on this. Cheers!

Collapse
 
teaglebuilt profile image
dillan teagle

haha thats great advice, thank you. I did not realize I left the most relevant tag out!

Collapse
 
highcenburg profile image
Vicente G. Reyes

haha no worries!

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay