How we made Social hub for the Osijek brewery?

Problem

We needed to create a custom post type in WordPress which pulls feed from the Instagram API and stores it in the database. A preview of every post which was loaded based on predefined hashtags related to the Osijek brewery was added to the admin dashboard. The user can also insert an ad  in every nth posts and limit posts that will be loaded on each AJAX call. The whole custom class in PHP is available on  the Blue Factory Github. The FrontEnd was created in ReactJS. The main reason is a big hype around React so we decided to play with new stuff. That day I wasn´t in the mood for HTML in jQuery. However, JSX syntax is quite readable, and the framework encourages programmers to write codes in an orderly fashion. The result was more than good!
social-hub

Implementation

First, we prepared a build task in Gulp, that allowed us to convert ES6 and React syntaxes into ES5 via Babel, which browsers can easily interprete. Using Browserify, I managed to import all the moduls together with the Pinterest plugin layout. I strongly suggest avoiding Pinterest layout for the following reasons :

  • You always need an extra library to be loaded, and depending on the size and its capabilities,  it can only be >100kb  because unnecessary waste of bandwidth on mobile devices is always a problem. Luckily,  on a cell phone,  the width of a post is 12 columns, but on a  tablet it isn´t.
  • Not many people can write a library on their own, and considering that there are ready solutions, that way is not profitable and you do not have any support (community or Github). It is clear which parameters the library receives, while the custom library always demands programmers to analyze and study the situation.

I have defined a function that gets  me back  all the necessary html,  which will later be executed in the Social hub:

function SocialHubElem({post, key}){
  let userProfileImg = {
     backgroundImage: 'url(' + post.user_profile_image + ')'
  };
  let featuredImg = {
    backgroundImage: 'url(' + post.image + ')'
  };
  let showBtn = () => {
    if(post.link && post.type == 'osjecko') {
      return <a href={post.link} className="button white">Pročitaj više</a>;
    }
    return;
  };
  return(
    <li key={key}>
      <a href={post.link} target="_blank">
        <span className={"social-media-icon " + post.type}></span>
        <div className="featured-img" style={featuredImg}>
          <div className="user-image" style={userProfileImg}></div>
        </div>
        <div className="post-content">
          <h5>{post.user_profile_name}</h5>
          <p className="post-date small">{post.date}</p>
          <div className="hashtags-wrapper" dangerouslySetInnerHTML={{__html: post.status}}></div>
          {showBtn()}
        </div>
      </a>
  </li>
)};

I could insert HTML directly inside component, but on this way we get the separation on the smart and dumb component. Smart component in this case is Social hub which contains the logic to read and print, and dumb component that is used to display data.
Social Hub use useful React lifecycle methods that allow us to execute some logic within the life cycle of components. In this case we used GetlnitialState() to said components what to expected at beginning. In this case it is an empty array, which will be completed after the execution AJAX calls. The important thing is that data types are consistent to avoid object if we expect the array and vice versa. I’ve used Lifecycle Hook component DidMount() so in it I could retrieve the getPosts() method which contains the only logic component:

getPosts: function() {
  let limit = postsPerPage;// * offset;
  let offset = this.refs.jsLoadBtn.dataset.offset * limit;
  let link = window.location.host + '/?social_hub_get=true&limit='+ limit +'&offset=' + offset; 
  $.get(link, function(){}).done(function(resp){
    this.setState({
      posts: this.state.posts.concat(resp.posts)
    });
   this.refs.jsLoadBtn.dataset.offset++;
  }.bind(this));
}

The limit is being extracted from PHP to JS variable. Offset had initialy been written in DOM so that we can reach it, and after every AJAX call it is being incremented so that we would essentialy know on which page we’re on, considering we have infinite loader. Inside the promise, we’re changing state which calls to re-rendering components, rendering only new posts and not previous ones (which is, by the way, the main reason I chose ReactJS). Using JS contact() method, I’m merging posts which have come with the previous posts which are currently under this.state, and I’m magnifying offset, so that I can know which page I’m on. What’s important is following „this“ value inside the application itself, because it’s changing depending on the executing method. This is why I used bind () method. At the top of the React class, I could have made „_this=this“, calling the methods with „_this.getPosts()“.
Later on, I made another method so that in it I could emulate clicking on the button „Load more posts“ (we don’t exactly have it because it’s an infinite loader which loads itself), where I’ve checked if the page is still at the top, and if the element on which we’ve emulated the click is visible, in which case we’re calling the method getPosts() which retrieves posts.

isVisible: function(isVisible) {
  let offset = $(window).scrollTop();
  if (isVisible === true && offset > 0 ) {
    this.getPosts();
  }
}

As a developer, I believe that React was the right tool for this little task, and it was fun to work with new technology. I believe that by using React router (which itself is a top level component) we can make simpler single page applications with suitable API for writing posts. Unfortunately, at the moment WordPress still doesn’t support writing custom post types using API.

We use cookies to optimize our website. By using our services, you agree to our use of cookies.