I’ve been reading a lot of articles over the last few months and one thing that I often noticed was disclaimers at the start saying that these posts were originally from their own website. Having written a few articles and wanting to increase my exposure, I decided that I wanted to have a blog on my site as well. But how to do it?
Options
There were a few possible options for incorporating a blog into my site but the main two are a custom content management system (CMS) or WordPress. I wanted to get it set up quickly so I went with using WordPress.
WordPress API
I’d heard a few things about the WordPress API over the last few weeks so started to Google. I set up a free blog at WordPress.com and imported my articles from Medium. This was super simple with Mediums export facility and WordPress’s “import from Medium” facility.
Now I had my articles on WordPress I had to figure out how to access them. I found this page in the documentation and I built a very basic web page to test with.
<h1>wordpress checker</h1>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="getWordpress.js"></script>
console.log("this is a proof of concenpt");
$.get(
"http://public-api.wordpress.com/rest/v1/sites/YourSite.wordpress.com/posts",
function(response) {
console.log(response);
}
);
This does the very simple task of calling the WordPress API and asking for all of the posts from “YourSite.wordpress.com”. From this I got a response object containing the number of posts and an array of each of the posts.
Routing
Now that I was going to have a Blog section to my site, I had to change from the single page that I previously had. I installed react-router-dom and imported BrowserRouter
and Route
into my layout file.
<BrowserRouter>
<div id="center-stripe">
<Nav />
<Route exact path="/" component={main} />
<Route exact path="/blog" component={Blog} />
</div>
</BrowserRouter>
Creating the Blog in React
My personal website is built using create-react-app and has a very basic structure. The next thing that I needed to do was to add a new “blog” page on which all of the article previews would be shown.
export default class Blog extends Component {
constructor(props) {
super(props);
this.state = {
posts: []
};
}
componentDidMount() {
axios
.get(
"http://public-api.wordpress.com/rest/v1/sites/samwcoding.wordpress.com/posts"
)
.then(res => {
this.setState({ posts: res.data.posts });
console.log(this.state.posts);
})
.catch(error => console.log(error));
}
render() {
return (
<div className="blog">
<h1 className="sectionTitle">Articles</h1>
{this.state.posts.map(post => <ArticlePreview post={post} />)}
</div>
);
}
}
I’ll talk you through this code. The top section sets the state of the component with an empty array of posts. Then I use the componentDidMount
function to execute the call to the WordPress API with axios. When the API call returns, I set this.state.posts to be the array of posts. This then causes line 24 to render an ArticlePreview
component for each of the posts.
render() {
if (this.props.post) {
return (
<div className="article">
<a href={"/blog/" + this.props.post.ID} className="blackLink">
{this.props.post.featured_image ? (
<img
className="img-responsive webpic"
alt="article header"
src={this.props.post.featured_image}
/>
) : (
""
)}
<h1 className="text-center">{this.props.post.title}</h1>
<div className="content">{excerpt}</div>
</a>
<Link to={"/blog/" + this.props.post.ID}>
<button className="btn">Read More</button>
</Link>
</div>
);
} else {
return null;
}
}
ArticlePreview takes each post and renders the preview with a title and excerpt, which are both provided by the WordPress API. If the post also has a featured image, it includes that too.
I reused a lot of the CSS from the rest of the website to style the articles previews and it looks quite good. One major error is the “
I’” and similar bits dotted throughout the excerpt. To solve this I set the excerpt to run though a removeUnicode()
function before being rendered to the screen. It simply replaced all ’
with just a comma and removed the <p>
and […]
tags. Its not elegant but it works.
Now I had the list of posts, I had to create a component for whole articles. I added another route for /blog/:id
and started on the new component. It was almost identical to the ArticlePreview
component, except that instead of rendering just the excerpt, it would render just one article. Getting the article from WordPress was very simple, just adding the article ID onto the end of the previous API call.
axios.get(
"http://public-api.wordpress.com/rest/v1/sites/samwcoding.wordpress.com/posts/" +
this.props.match.params.id
)
Getting the article response is where I hit my first stumbling block. The body of the article was all in stringified HTML format. I found a solution with the dangerouslySetInnerHTML
function. (If anyone has any suggestions on how to implement this better then please let me know).
With this done I had a few changes to make. The nav buttons at the top just connected to anchor tags and that worked fine on a single page website but now they were sending users to /blog#about
which doesn’t work. This was solved by defining the link specifically as /#about
and /#projects
.
The blog now works well with the number of articles I currently have written but how will it cope when there are 50 or 100 articles? In the future I may have to render a few of the article previews at a time, rendering more if the user scrolls to the bottom. Another feature I could add would be searching.
Checkout the blog at SamWSoftware blog and view my whole code here.