<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>WordPress Archives - Michael Soriano</title>
	<atom:link href="https://michaelsoriano.com/category/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>https://michaelsoriano.com/category/wordpress/</link>
	<description>I turn code into captivating user experiences for the web</description>
	<lastBuildDate>Fri, 09 Aug 2024 21:32:54 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.4</generator>
	<item>
		<title>How to create an Accordion Block using React and WordPress&#8217; Block API</title>
		<link>https://michaelsoriano.com/how-to-create-an-accordion-block-using-react-and-wordpress-block-api/</link>
					<comments>https://michaelsoriano.com/how-to-create-an-accordion-block-using-react-and-wordpress-block-api/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Mon, 06 Nov 2023 23:03:50 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">https://michaelsoriano.com/?p=7969</guid>

					<description><![CDATA[<p>I was tasked with creating a custom component for our public website which runs on WordPress. Most commonly known as an &#8220;Accordion&#8220;, it is a section of a page where you can have a title and an expandable and collapsible directly underneath it. Usually a list of these items are blocked together &#8211; forming an [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/how-to-create-an-accordion-block-using-react-and-wordpress-block-api/">How to create an Accordion Block using React and WordPress&#8217; Block API</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I was tasked with creating a custom component for our public website which runs on WordPress. Most commonly known as an &#8220;<em>Accordion</em>&#8220;, it is a section of a page where you can have a title and an expandable and collapsible directly underneath it. Usually a list of these items are blocked together &#8211; forming an &#8220;accordion&#8221; like pattern. </p>



<p>In HTML, this is easily achieved by the &#8220;<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details"><strong>Details</strong></a>&#8221; element. But of course, our users cannot write HTML. Similarly, a default block already exists in WordPress called &#8220;<em>details</em>&#8220;. The problem with this one is that our users do not find it intuitive. Also, they want to limit the formatting of the contents for each item. </p>



<figure class="wp-block-image size-large border"><img fetchpriority="high" decoding="async" width="1024" height="510" src="https://michaelsoriano.com/wp-content/uploads/2023/11/image-1024x510.png" alt="" class="wp-image-7973" srcset="https://michaelsoriano.com/wp-content/uploads/2023/11/image-1024x510.png 1024w, https://michaelsoriano.com/wp-content/uploads/2023/11/image-300x149.png 300w, https://michaelsoriano.com/wp-content/uploads/2023/11/image-768x383.png 768w, https://michaelsoriano.com/wp-content/uploads/2023/11/image-1536x765.png 1536w, https://michaelsoriano.com/wp-content/uploads/2023/11/image.png 1662w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>You see how each item is contained within a big block. A button will add a title/content pair to the list &#8211; along with a checkbox that allows for the section to be expanded or collapsed by default. </p>



<h3 class="wp-block-heading">Register the Block </h3>



<p>This is the &#8220;housekeeping&#8221; part of the codebase. There is a PHP part of this process &#8211; and it really depends if you&#8217;re putting this in a plugin or a theme. But main function is below:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">register_block_type(
    'namepsace/my-blocks-accordion',  // Block name with namespace
    [
        'style' => 'accordion-style',  
        'editor_style' => 'accordion-edit-style', 
        'editor_script' => 'accordion-js'  
    ]
);
...</code></pre>



<p>Also, there are other parts of this such as enqueuing the styles and scripts for your blocks &#8211; which I&#8217;m not going to cover here. We&#8217;re mostly focusing on the &#8220;client&#8221; or JS side of things. </p>



<p>To read more about registering blocks in WordPress &#8211; see the <a href="https://developer.wordpress.org/reference/functions/register_block_type/">codex</a>.  </p>



<p>For the JavaScript, create a file called <em>index.js</em> and start with the <strong>registerBlockType</strong>() function. If you&#8217;re not familiar with how to build blocks for WP &#8211; this is a good start <a href="https://developer.wordpress.org/block-editor/getting-started/create-block/block-anatomy/">Anatomy of a Block | Block Editor Handbook | WordPress Developer Resources</a>.</p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx">registerBlockType(
    'namespace/accordion', {
      title: __('Accordion'),  
      icon: 'list-view',
      category: 'my-blocks', 
      attributes : {
        items : { 
         type: 'array',
         default : []
     }
    ...
}</code></pre>



<p>Pay extra attention to the &#8220;<em>attributes</em>&#8221; object. This is the main &#8220;context&#8221; of our application. Notice that we want an array called &#8220;items&#8221; inside attributes &#8211; this is where we&#8217;ll manage our data.  </p>



<h3 class="wp-block-heading">The &#8220;Edit&#8221; Component</h3>



<p>So in Gutenberg Blocks, the two major components that we have to worry about is the &#8220;Edit&#8221; and &#8220;Save&#8221;. Edit is what you see during the editing of Posts or Pages. Let&#8217;s look at how to build this first &#8211; particularly the JSX section:</p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx">const { RichText } = wp.editor;  
const { __ } = wp.i18n;

...

title: __('Accordion'),  
icon: 'list-view',
category: 'my-blocks', 
attributes : {
   items : { 
     type: 'array',
     default : []
   }
},
edit ( {className, attributes, setAttributes} ) {

... 

return (
&lt;div>
{attributes.items &amp;&amp; attributes.items.length > 0 ? attributes.items.map((item,i) => {
return (
&lt;div>
    &lt;div className={`${className}-item-title-wrap`}>
    &lt;RichText   
        allowedFormats={[]}   
        tagName="div"     
        placeholder="Enter Title"               
        className={ `${className}-item-title` }
        value={ item.title }
        disableLineBreaks={ true }
        onChange={ val => updateItemTitle(val,i)}
    />
    &lt;label>
    &lt;input type="checkbox" data-index={i}
        checked={item.expand} 
        onChange={e=>updateItemExpand(e)} />
        Expanded
    &lt;/label>
    &lt;/div>
    &lt;RichText  
        placeholder="Enter Content"  
        allowedFormats={ ['core/bold','core/italic','core/link'] }    
        multiline="p"
        tagName="div"                    
        className={ `${className}-item-content` }
        value={item.content}
        onChange={ val => updateItemContent(val,i)}
    />
&lt;/div>
)
}) : null}
&lt;button 
    className={ `${className}-add-btn` } 
    onClick={addEmptyItem}>Add Accordion Item&lt;/button>
&lt;/div>
);

} //END EDIT</code></pre>



<p>The HTML above is the UI for our editors. Notice that we&#8217;re going through out &#8220;<em>items</em>&#8221; and outputting it for action. We&#8217;re using the built-in <strong>RichText</strong> component for our editable sections (title and content). RichText is awesome &#8211; <a href="https://developer.wordpress.org/block-editor/reference-guides/richtext/">find out</a> more about it. We&#8217;re also including a checkbox called <em>expanded</em> &#8211; that will allow our users to show the item expanded or collapsed. </p>



<h3 class="wp-block-heading">Adding Items</h3>



<p>When first using the block &#8211; all you see is a button that says &#8220;<em>Add Accordion Item</em>&#8220;. Clicking this button will execute below:</p>



<pre class="wp-block-code"><code lang="JavaScript" class="language-JavaScript">const addEmptyItem = () =&gt; {
    const items = [...attributes.items, {
      title : '', 
      content : '', 
      expand : true
    }];
   setAttributes({items})
}</code></pre>



<p>This will add an empty object to our Attributes Items array, allowing our users to be able to edit our RichText components. </p>



<h3 class="wp-block-heading">Click and Change Handlers</h3>



<p>If you look in our JSX, we&#8217;ve mapped our inputs to event handlers. Add the code below&#8221;</p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx">const updateItemExpand= (e) => {
    const items = attributes.items.slice();
    const index = e.target.attributes.getNamedItem('data-index').value;
    items[index].expand = e.target.checked;
    setAttributes({items})
}
const updateItemTitle = (title,i) => {
    const items = attributes.items.slice();
    items[i].title = title;
    setAttributes({items})
}
const updateItemContent = (content,i) => {
    const items = attributes.items.slice();
    items[i].content = content;
    setAttributes({items})
}</code></pre>



<p>The function names are pretty self explanatory. All we&#8217;re doing is manipulating the data in our Attributes. Also notice the <strong>setAttributes</strong>() function we&#8217;re using in each function. This is a &#8220;setter&#8221; that is very similar to React&#8217;s <em>useState</em> setters.  </p>



<p>With all that in place, our Accordion block is ready for editing:</p>



<figure class="wp-block-image size-full border wp-duotone-unset-1"><img decoding="async" width="923" height="520" src="https://michaelsoriano.com/wp-content/uploads/2023/11/accordion-block-edit.gif" alt="" class="wp-image-7971"/></figure>



<p>Typing &#8220;<em>/accordion</em>&#8221; will insert our block &#8211; ready for editing. </p>



<h3 class="wp-block-heading">The &#8220;Save&#8221; Component</h3>



<p>This is simply JSX that outputs our HTML for the public users. The code for this is quite simple &#8211; we&#8217;re simply using &#8220;<strong>details</strong>&#8221; and &#8220;<strong>summary</strong>&#8220;. This automatically has the expand and collapse functionality out of the box.</p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx">save( { attributes } ) {
    return (
        &lt;div>
        {attributes.items &amp;&amp; attributes.items.length > 0 ? (
            attributes.items.map(item => {
                return (
                    &lt;details open={item.expand}>
                    &lt;summary>{item.title}&lt;/summary>
                    &lt;div dangerouslySetInnerHTML={
                       {__html: item.content}
                    } /> 
                    &lt;/details>
                )
            })
        ) : null}
        &lt;/div>
        )
    } 
}</code></pre>



<p>Notice the use of <em>dangerouslySetInnerHTML</em> &#8211; because we&#8217;re outputting HTML content from WordPress. If this can be done in other ways leave a comment below. </p>



<p>Styling the output with some CSS:</p>



<pre class="wp-block-code"><code lang="css" class="language-css">.wp-block-my-blocks-accordion {
    margin-bottom: 25px;
}

.wp-block-my-blocks-accordion details > summary {
    background:url('/images/arrow-down.png') no-repeat;
    background-size: 13px;
    background-position-x: right;
    background-position-y: 10px;
    font-weight: 500;
    border-bottom:1px solid #ebebeb;
    margin-bottom: 10px;
    padding-bottom: 6px;
    cursor:pointer;
}
.wp-block-my-blocks-accordion details[open] > summary {
    background:url('images/arrow-up.png') no-repeat;
    background-size: 13px;
    background-position-x: right;
    background-position-y: 10px;
} 
.wp-block-my-blocks-accordion details > summary:hover {
    opacity: 0.6;
}  
.wp-block-my-blocks-accordion details > summary > * {
    display: inline;
}</code></pre>



<p>We&#8217;re simply overriding the default look of the details component &#8211; specifically the arrows. I prefer to see them in the right instead of left. Also, adding a subtle border to make it look better. </p>



<p>And with that in place &#8211; it should look like below when the post is saved:</p>



<figure class="wp-block-image size-full border"><img decoding="async" width="788" height="494" src="https://michaelsoriano.com/wp-content/uploads/2023/11/accordion-block-view.gif" alt="" class="wp-image-7972"/></figure>



<p>There you have it. We&#8217;ve just made our own custom Gutenberg block. This was pretty fun to build &#8211; and learning about the Block API is quite straightforward. It&#8217;s very much like classic React &#8211; but simpler.</p>



<p>Be sure to leave your thoughts below.</p>
<p>The post <a href="https://michaelsoriano.com/how-to-create-an-accordion-block-using-react-and-wordpress-block-api/">How to create an Accordion Block using React and WordPress&#8217; Block API</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/how-to-create-an-accordion-block-using-react-and-wordpress-block-api/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Let’s build a WordPress theme with React: Part 3 (The Loop)</title>
		<link>https://michaelsoriano.com/lets-build-a-wordpress-theme-with-react-part-3-the-loop/</link>
					<comments>https://michaelsoriano.com/lets-build-a-wordpress-theme-with-react-part-3-the-loop/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Thu, 03 Oct 2019 21:24:06 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[React]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6985</guid>

					<description><![CDATA[<p>Okay its been a while since I last posted. Let&#8217;s continue with Barebones React WP theme. The last time we left off, we introduced the concept of &#8220;The Loop&#8220;. But we really didn&#8217;t get into what its all about. Let&#8217;s describe what this piece is doing. In WordPress themes &#8211; there is the &#8220;The Loop&#8220;, [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/lets-build-a-wordpress-theme-with-react-part-3-the-loop/">Let’s build a WordPress theme with React: Part 3 (The Loop)</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Okay its been a while since I last posted. Let&#8217;s continue with Barebones React WP theme. The last time we left off, we introduced the concept of &#8220;<strong>The Loop</strong>&#8220;. But we really didn&#8217;t get into what its all about. Let&#8217;s describe what this piece is doing. </p>



<figure class="wp-block-image size-full"><img decoding="async" width="700" height="400" src="https://michaelsoriano.com/wp-content/uploads/2019/05/react-wp.jpg" alt="react wordpress" class="wp-image-6940" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/react-wp.jpg 700w, https://michaelsoriano.com/wp-content/uploads/2019/05/react-wp-300x171.jpg 300w" sizes="(max-width: 700px) 100vw, 700px" /></figure>



<p>In WordPress themes &#8211; there is the &#8220;<a href="https://codex.wordpress.org/the_loop">The Loop</a>&#8220;, where it&#8217;s a &#8220;catch all&#8221; for all of the post content at a given query. This may be a page, a post or a series of posts. It all goes to &#8220;<strong>The Loop</strong>&#8220;, where inside that loop &#8211; are methods that make retrieving post data easy. Inside the loop, we can do something like &#8220;<em>get_the_ID()</em>&#8221; or &#8220;<em>the_title()</em>&#8221; &#8211; which will output the post id or its title. </p>



<p>We&#8217;re trying to achieve the same thing in Barebones. We have &#8220;TheLoop&#8221; component &#8211; which we&#8217;ll be adding in our &#8220;partials&#8221; directory. This component will be used everywhere &#8211; in single posts, pages or archive pages such as search etc. </p>



<p>Previously, we were just outputting the slug in TheLoop. The modified version is shown below. </p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">import React from 'react';
import WithConsumer from '../context/WithConsumer';
import ThePost from './ThePost';
const TheLoop = ({ context }) =&gt; {
    const posts = () =&gt; context.posts;
    const pos = posts();
    let results = '';
    if(context.appError){
      results = &lt;div className="app-error"&gt;{context.appError}&lt;/div&gt;;
    }else{
      if(pos.length === 0){
        results = &lt;div className="no-results"&gt;no results&lt;/div&gt;;
      }else{
        results = pos.map(function(item,i){
             return &lt;ThePost key={i} index={i}&gt;&lt;/ThePost&gt;
           })
      }
    }
    return (results);
};
export default WithConsumer(TheLoop);</code></pre>



<p>There&#8217;s really not a lot going on. We are simply isolating the &#8220;loop&#8221; logic in this component. So we don&#8217;t have to do the same elsewhere. But the key points to see is we&#8217;re getting the results from our Context. And depending on the count of the result, if there&#8217;s more than 0, we &#8211; return the &#8220;<strong>ThePost</strong>&#8221; component (more on this later).</p>



<p>If there&#8217;s no results &#8211; we simply return a div with the text &#8220;no results&#8221;. </p>



<p>If  there&#8217;s an error &#8211; return the error message. </p>



<h3 class="wp-block-heading">ThePost</h3>



<p>ThePost component has all of the methods necessary to output the post data. This resembles WP&#8217;s &#8220;<strong>the_post()</strong>&#8221; in PHP. In here, we have access to the context.posts, filtered by the index. The index is a prop that we pass coming from TheLoop. So now, each <strong>item</strong> is a post:</p>



<pre title="ThePost" class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">const ThePost = ({index,context}) =&gt; {
    const posts = () =&gt; context.posts;
    const item = posts()[index];
    let linkPrefix = item.type === 'page' ? '/page/' : '/post/';
    let theContent = '';
    switch(context.route){
        case '/': //if homepage,
        case '/search/:term': //or if search
        case '/category/:catid': //or if search
            theContent = item.excerpt.rendered; //show excerpt only
        break;
        default: //for single, pages - show entire content
            theContent = item.content.rendered;
        break;
    }
    return (
        &lt;div id={'post-id-'+item.id} className={'post-item'}&gt;
            &lt;h1&gt;&lt;Link to={linkPrefix+item.slug}&gt;{item.title.rendered}&lt;/Link&gt;&lt;/h1&gt;
            &lt;PostMeta index={index}&gt;&lt;/PostMeta&gt;
            &lt;div className="post-content" dangerouslySetInnerHTML={{__html:theContent}}&gt;&lt;/div&gt;
        &lt;/div&gt;);
};</code></pre>



<p>We have to determine if its a &#8220;post&#8221; or a &#8220;page&#8221; (line 6). This will match with the post/page route in our <em>index.js</em>.  </p>



<p>Then we have a switch statement, that checks the route. If its an archive page (like search, category) &#8211; let&#8217;s output only the content excerpt. Otherwise &#8211; if its a single, let&#8217;s output the entire thing. </p>



<p>The PostMeta component is also a new component that we haven&#8217;t built yet. Let&#8217;s add that in a little bit. For now, let&#8217;s grab the data.</p>



<h3 class="wp-block-heading"><strong>Context</strong>.js</h3>



<p>Now there are a few things we need to do to our Context component for the loop to work. Remember in our loop, we&#8217;ve setup up the links using &#8220;Link to&#8221;. We need to map these links to right REST url endpoint &#8211; so we can get the right data and put it in the right data store. </p>



<p>Remember, all of the data is inside this one file. May it be posts, comments &#8211; even methods that manipulate this data is in this component. So this file is extremely important. </p>



<p>Let&#8217;s start by adding the containers for our state. In the constructor, add the following:</p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx">constructor(props) {
    super(props);
    let restType = this.getRestType(props.router.match.path);
    let route = props.router.match.path;
    let slug = props.router.match.params.slug ? props.router.match.params.slug : '';
    this.state = {
      slug : slug,
      restType : restType,
      route : route,
      posts : []
    };
  }</code></pre>



<p>Our state now has the necessary containers for the data we need. Primarily the &#8220;posts&#8221; array is what we aim to fill. Let&#8217;s add some actions in our lifecycle hook: componentDidMount:</p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx">componentDidMount(){
    this.getPosts(this.buildUrl());
}</code></pre>



<p>Let&#8217;s build a couple of functions &#8211; one to build the REST url endpoint, and the other to fetch the posts: </p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">buildUrl(){
    let url = '/wp-json/wp/v2/';
    switch(this.state.restType){
      case 'page':
        url += 'pages/?slug=' + this.state.slug
      break;
      case 'post':
      default:
        url += 'posts/?slug=' + this.state.slug ;
        break;
    }
    return url;
  }
 getPosts (url){
    let self = this;
    Axios.get(url).then((response)=&gt;{
      self.setState({
        posts : response.data
    }).catch(function(error){
      console.log(error);
      self.appError = 'An unexpected error occurred';
    });
  }
</code></pre>



<p>That should set our post and page endpoints, bringing back data from the API.  Make sure that TheLoop is in your Archive and Single components. </p>



<p>And if all is good, we should have something like below: </p>



<figure class="wp-block-image border"><img decoding="async" width="700" height="527" src="https://michaelsoriano.com/wp-content/uploads/2019/06/post-page.gif" alt="" class="wp-image-6986"/></figure>



<p>Remember that we have to change our permalinks in WordPress to match our route. </p>



<h3 class="wp-block-heading">Add Paging</h3>



<p>Paging is necessary especially for archive pages. You only want to see the latest X number of posts, then show the next X &#8211; and so on. </p>



<p>In <strong>Archive.js</strong> &#8211; simply add the pager component (that we still have to build), right underneath the loop:</p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx"> &lt;TheLoop&gt;&lt;/TheLoop&gt;
 &lt;Pager&gt;&lt;/Pager&gt;</code></pre>



<p>Now let&#8217;s create a file in our partials folder &#8211; call it <strong>Pager.js</strong>. </p>



<pre title="Pager.js" class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">import React, { useEffect } from 'react';
import WithConsumer from '../context/WithConsumer';
const Pager = function ({context}){
    let prevBtn =  React.createRef();
    let nextBtn =  React.createRef();
    let curPage = () =&gt; context.currentPage;
    let totalPages = () =&gt; context.totalPages;
    useEffect(() =&gt; {
        prevBtn.current.disabled = true;
        // eslint-disable-next-line react-hooks/exhaustive-deps
    },[]);
    function nextClicked(){
        context.nextClicked();
        if(parseInt(totalPages()) === parseInt(curPage() + 1) ){
            nextBtn.current.disabled = true;
        }
        prevBtn.current.disabled = false;
    }
    function previousClicked(){
        context.previousClicked();
        if(parseInt(curPage()-1) === 1 ){
            prevBtn.current.disabled = true;
        }
        nextBtn.current.disabled = false;
    }
    function pagerClass(){
        let cls = 'Pager';
        if(parseInt(totalPages()) &lt;=1 ||
            context.appError){
            cls = 'Pager hidden';
        }
        return cls;
    }
    return (
        &lt;div className={pagerClass()}&gt;
        &lt;button ref={prevBtn} onClick={previousClicked}&gt;Previous&lt;/button&gt;
        &lt;button ref={nextBtn} onClick={nextClicked}&gt;Next&lt;/button&gt;
        &lt;div className="PagerText"&gt;Page
            &lt;span dangerouslySetInnerHTML={{__html: curPage()}}&gt;&lt;/span&gt; of
            &lt;span dangerouslySetInnerHTML={{__html: totalPages()}}&gt;&lt;/span&gt;&lt;/div&gt;
        &lt;/div&gt;
    )
}
export default WithConsumer(Pager);</code></pre>



<p>Now the pager logic is a little more involved. Above simply outputs our &#8220;Next&#8221; and &#8220;Previous&#8221; buttons &#8211; depending on the number of pages. Fortunately, WordPress&#8217;s API makes this easy for us. We have 2 important header properties from each response called &#8221; X-WP-Total&#8221; and &#8221; X-WP-TotalPages&#8221;. From this we can determine the logic needed for our paging.</p>



<p>Going back to context, we need to modify our state, add some methods that modify that state, as well as modify our rest calls.</p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx">//ADD THIS TO this.state IN THE CONSTRUCTOR
currentPage : 1,
totalPages : 0,
nextClicked : this.nextClicked.bind(this),
previousClicked : this.previousClicked.bind(this), </code></pre>



<p>Above shows our new state. Note that currentPage always starts at 1. Totalpages &#8211; we update on every call, then we bind 2 methods to &#8220;this&#8221;. </p>



<p>Next, let&#8217;s add modify our <strong>buildUrl()</strong> method to have the page parameters from our state. </p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx"> case 'post':
      default:
        url += this.state.slug ? 'posts/?slug=' + this.state.slug : 'posts/?page=' + this.state.currentPage;
        break;    </code></pre>



<p>Above simply appends the current page to the url endpoint. In our <strong>getPosts()</strong> method, we update our totalPages in state with each response: </p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx">Axios.get(url).then((response)=&gt;{
      self.setState({
        posts : response.data,
        totalPages : response.headers['x-wp-totalpages']
      }</code></pre>



<p>Now all we need to do is create two functions &#8211; which correspond to which button was clicked: </p>



<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">  nextClicked (){
    let newPage = this.state.currentPage + 1;
    this.setState({
      currentPage : newPage
    },function(){
      this.getPosts(this.buildUrl());
    })
  }
  previousClicked (){
    let newPage = this.state.currentPage - 1;
    this.setState({
      currentPage : newPage
    },function(){
      this.getPosts(this.buildUrl());
    })
  }</code></pre>



<p>Both of these methods are called from our Pager component &#8211; which we access by doing <em>context.XXXClicked()</em>. Pretty neat right? </p>



<p>We also let the front end decide whether to show or hide the respective buttons. So if all goes well, we have something like below: </p>



<figure class="wp-block-image border"><img decoding="async" width="700" height="572" src="https://michaelsoriano.com/wp-content/uploads/2019/06/paging.gif" alt="" class="wp-image-6988"/></figure>



<p>Okay that should be it for this round. A lot going on above. I suggest you download the <a href="https://github.com/michaelsoriano/barebones">code</a> and run it yourself &#8211; along with following the steps. Note there are a lot of omitted code above. Only the important steps are outlined &#8211; the rest is up to you.</p>
<p>The post <a href="https://michaelsoriano.com/lets-build-a-wordpress-theme-with-react-part-3-the-loop/">Let’s build a WordPress theme with React: Part 3 (The Loop)</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/lets-build-a-wordpress-theme-with-react-part-3-the-loop/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Let’s build a WordPress theme with React: Part 2 (Routes + Context)</title>
		<link>https://michaelsoriano.com/wordpress-theme-react-part-2-routes-context/</link>
					<comments>https://michaelsoriano.com/wordpress-theme-react-part-2-routes-context/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Mon, 15 Jul 2019 04:10:50 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[React]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=7030</guid>

					<description><![CDATA[<p>Now that we have our react app setup, let&#8217;s form how our application will be structured. We&#8217;re going to need 3 main folders: 1) templates, 2) partials and 3) context. These are all going to be inside react-src/src folder. The templates folder is where we&#8217;re going to store the main files template files &#8211; namely [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/wordpress-theme-react-part-2-routes-context/">Let’s build a WordPress theme with React: Part 2 (Routes + Context)</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><!--StartFragment--></p>

<p>Now that we have our react app setup, let&#8217;s form how our application will be structured. We&#8217;re going to need 3 main folders: 1) <em>templates, </em>2) <em>partials </em>and 3) <em>context</em>. These are all going to be inside <strong>react-src/src</strong> folder.</p>


<p>The <strong>templates</strong> folder is where we&#8217;re going to store the main files template files &#8211; namely <em>Single.js</em> and <em>Archive.js.</em> Single shows a single post, while Archive shows a running list of post in reverse chronological order. </p>


<p>The <strong>partials</strong> contain bits and pieces of reusable parts. These are files that make up the header, navigaition, pagination and the loop.</p>


<p>The <strong>context</strong> is where the data sits. We&#8217;re going to have two files in here &#8211; <em>Context.js</em> and <em>WithConsumer.js</em>. These files are what we need to store state and props. More on this later. </p>


<p>Also, don&#8217;t forget that we have our <strong>public</strong> folder (which is outside the src directory). This contains all the regular PHP files such as functions.php etc.</p>


<h3 class="wp-block-heading">Routes</h3>


<p>Let&#8217;s begin by adding a simple route. Make sure we&#8217;re in development mode by running:</p>


<pre class="wp-block-code"><code lang="javascript" class="language-javascript">npm run wpstart</code></pre>


<p>Let&#8217;s create a new component called &#8220;Single&#8221;. Inside it, let&#8217;s start simple and put in the code below: </p>


<pre class="wp-block-code"><code lang="javascript" class="language-javascript">import React from 'react';
const Single = (props) => {
    return (
        &lt;div className="Post">
            this is the page component
        &lt;/div>
    )
}
export default Single;</code></pre>


<p>Pretty basic right? Now let&#8217;s install react router by running the command below: </p>


<pre class="wp-block-code"><code lang="javascript" class="language-javascript">npm install react-router-dom</code></pre>


<p>Open up <strong>index.js</strong> and include react router in it</p>


<pre class="wp-block-code"><code lang="bash" class="language-bash">import { BrowserRouter, Switch, Route } from 'react-router-dom';</code></pre>


<p>Inside the render function, let&#8217;s modify it to look like this: </p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">ReactDOM.render(
&lt;BrowserRouter>
    &lt;Switch>
     &lt;Route path='/page' component={Single}/>
    &lt;/Switch>
  &lt;/BrowserRouter>, document.getElementById('root'));</code></pre>


<p>Now navigate to your site, but append the path &#8220;/page&#8221;. You should see your page component rendered. </p>


<figure class="wp-block-image"><img decoding="async" width="599" height="487" src="https://michaelsoriano.com/wp-content/uploads/2019/06/page-component.png" alt="" class="wp-image-6970" srcset="https://michaelsoriano.com/wp-content/uploads/2019/06/page-component.png 599w, https://michaelsoriano.com/wp-content/uploads/2019/06/page-component-300x244.png 300w" sizes="(max-width: 599px) 100vw, 599px" /></figure>


<p>Now let&#8217;s go back to <strong>index.js</strong> and modify the Route to look like below:</p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx">&lt;Route path="/page/:slug" component={Single} />    </code></pre>


<p>Notice we&#8217;re adding a <strong>:slug</strong> to the path. We&#8217;re going to be updating our component with this parameter. The slug will be the actual &#8220;slug&#8221; of the WordPress post. If you modify our page component with:</p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx">&lt;h1>this is the slug: {props.match.params.slug}&lt;/h1></code></pre>


<p>You should see something like below:</p>


<figure class="wp-block-image"><img decoding="async" width="599" height="430" src="https://michaelsoriano.com/wp-content/uploads/2019/06/slug.png" alt="" class="wp-image-6971" srcset="https://michaelsoriano.com/wp-content/uploads/2019/06/slug.png 599w, https://michaelsoriano.com/wp-content/uploads/2019/06/slug-300x215.png 300w" sizes="(max-width: 599px) 100vw, 599px" /></figure>


<p>So by now, you should see how we&#8217;re going to continue with our theme. We&#8217;re going to be adding the following routes:</p>


<ul class="wp-block-list"><li>Home &#8211; mapped to &#8220;Archive&#8221;</li><li>Page + slug &#8211; mapped to &#8220;Single&#8221;</li><li>Post + slug &#8211; mapped to &#8220;Single&#8221;</li><li>Search + term &#8211; mapped to &#8220;Archive&#8221;</li><li>404 &#8211; mapped to &#8220;404&#8221;</li></ul>


<p>Go ahead and copy the Single component, duplicate it &#8211; and call it &#8220;Archive&#8221;.  Then let&#8217;s match it to the routes above. </p>


<p>Our <strong>index.js</strong> now looks like below:</p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">import React from 'react';
import ReactDOM from 'react-dom';
import { Route, BrowserRouter as Router, Switch } from 'react-router-dom'
import './index.css';
import Archive from './templates/Archive';
import Single from './templates/Single';
import Notfound from './templates/Notfound';
const routes = (
    &lt;Router>
      &lt;Switch>
           &lt;Route exact path="/" component={Archive} />
           &lt;Route path="/page/:slug" component={Single} />
           &lt;Route path="/post/:slug" component={Single} />
           &lt;Route path="/search/:term" component={Archive} />
           &lt;Route component={Notfound} />
      &lt;/Switch>
    &lt;/Router>
  )
ReactDOM.render(routes, document.getElementById('root'));</code></pre>


<p><strong>Partials</strong></p>


<p>Let&#8217;s quickly talk about our partials. Partials are components that we will be reusing in each route component. Things that come to mind are header, footer, sidebar &#8211; and whichever reusable piece of code we will come across along the way.</p>


<p>Let&#8217;s go ahead and create 2 partials. <strong>Head.js</strong> and <strong>Foot.js</strong>. These will be the header and footer of our pages. The code will be a simple functional component like below:</p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">/******Head.js*************/
import React from 'react'
function Head(){
    return (&lt;div className="header">header&lt;/div>)
}
export default Head;
/******Foot.js*************/
import React from 'react'
function Foot(){
    return (&lt;div className="footer">footer&lt;/div>)
}
export default Foot;</code></pre>


<p>Now in our template components, simply import, and add the components in. Here is the how our <strong>Single.js</strong> will look like with the partials. Note &#8211; make sure you add them inside the main div:</p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">import React from 'react'
import Head from '../partials/Head';
import Foot from '../partials/Foot';
const Single = (props) => {
    return (
        &lt;div className="Post">
            &lt;Head>&lt;/Head>
            &lt;h1>Home&lt;/h1>
            &lt;Foot>&lt;/Foot>
        &lt;/div>
    )
}
export default Single</code></pre>


<p>In the browser, you will see our partials and home page starting to take shape. Inspect the code and it should look like below:</p>


<figure class="wp-block-image"><img decoding="async" width="678" height="424" src="https://michaelsoriano.com/wp-content/uploads/2019/06/partials.gif" alt="" class="wp-image-6978"/></figure>


<p>Do the same thing to the rest of our main components so they all share the same header and footer. </p>


<h3 class="wp-block-heading">Context (Data)</h3>


<p>As mentioned above, this is where our data will sit. React has <a href="https://reactjs.org/docs/context.html">Context API</a> which allows you to have a centralized data store &#8211; so that you don&#8217;t have to pass data through each child component. This <a href="https://medium.com/datadriveninvestor/getting-started-w-reacts-context-api-f60aa9be758f">article</a> is probably the best explanation on Context API. As a matter of fact, the two files that we&#8217;re going to build, is code that came from the article. </p>


<p>Let&#8217;s start with <strong>Context.js</strong>. This file is considered to be the &#8220;<em>Provider</em>&#8220;. Add the code below:</p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">import React from "react";
const storeContext = React.createContext();
export const Consumer = storeContext.Consumer;
export class Provider extends React.Component {
  constructor(props) {
    super(props);
     this.state = {
      posts : []
    };
  }
 componentDidMount(){
    this.setState({
       posts : ['title','title2']
    })
 }
 componentDidUpdate(prevProps){
    //more code here later...
 }
 render() {
    return (
      &lt;storeContext.Provider value={this.state}>
        {this.props.children}
      &lt;/storeContext.Provider>
    );
  }
} </code></pre>


<p>Don&#8217;t worry so much about the test posts data. We&#8217;re just using that for &#8211; well, testing. Then let&#8217;s create <strong>WithConsumer.js</strong></p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">import React from "react";
import { Consumer } from "./Context";
function WithConsumer(WrappedComponent) {
  return function(props) {
    return (
      &lt;Consumer>
        {ctx => &lt;WrappedComponent {...props} context={ctx} />}
      &lt;/Consumer>
    );
  };
}
export default WithConsumer;</code></pre>


<p>Now this one is pretty confusing. It&#8217;s basically a wrapper &#8211; for our components that require the &#8220;Consumer&#8221; component. Basically, all our components that want to &#8220;consume&#8221; data from our &#8220;Provider&#8221; will be using this file. </p>


<p>Now let&#8217;s create a partial called &#8220;<strong>TheLoop</strong>&#8220;. Add the code below:</p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx line-numbers">import React from 'react';
import WithConsumer from '../context/WithConsumer';
const TheLoop = ({ context }) => {
    const posts = () => context.posts;
    const pos = posts();
    return (
       pos.map(function(item,i){
         return &lt;div key={i}>{item}&lt;/div>
       })
    );
};
export default WithConsumer(TheLoop);</code></pre>


<p>Notice that in our export &#8211; we&#8217;re passing our component <strong>TheLoop</strong> as a parameter to <strong>WithConsumer</strong>.  </p>


<p>We&#8217;re going to talk more in detail about <strong>TheLoop</strong> component in our next session. For now, we just want to get it up and running &#8211; to demonstrate Context and Consumer. </p>


<p>Let&#8217;s open <strong>Single.js</strong> from our templates folder and modify it to look like this:</p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx">import React from 'react';
import Head from '../partials/Head';
import TheLoop from '../partials/TheLoop';
import Foot from '../partials/Foot';
import {Provider} from '../context/Context'
const Single = (props) => {
  return (
    &lt;Provider>
    &lt;div className="Post">
      &lt;Head>&lt;/Head>
      &lt;TheLoop>&lt;/TheLoop>
      &lt;Foot>&lt;/Foot>
    &lt;/div>
    &lt;/Provider>
  )
}
export default Single</code></pre>


<p>You see how we&#8217;re wrapping everything in &#8220;<strong>&lt;Provider&gt;</strong>&#8220;, this is so we have access to our <strong>Context.js</strong> data. Also, we&#8217;ve included &#8220;<strong>TheLoop</strong>&#8221; as a component in between Head and Foot. </p>


<p>You should see &#8220;title&#8221; and &#8220;title2&#8221; in the browser by now. </p>


<p>Lastly, we need a way to get our &#8220;slug&#8221; parameter into our context. We can use props for that. Still in <strong>Single.js</strong>, pass the slug via props like so:</p>


<pre class="wp-block-code"><code lang="jsx" class="language-jsx">&lt;Provider router={props}></code></pre>


<p>In <strong>Context.js</strong>, we should have access to the slug &#8211; through &#8220;<strong>props.router.match.params.slug</strong>&#8220;. As a matter of fact, we have access to the entire router object here, in a prop called &#8220;router&#8221;. </p>


<p>Let&#8217;s stop here for now. We are going to discuss more about <strong>TheLoop</strong> and Axios in our next session.</p>

<p><!--EndFragment--></p><p>The post <a href="https://michaelsoriano.com/wordpress-theme-react-part-2-routes-context/">Let’s build a WordPress theme with React: Part 2 (Routes + Context)</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/wordpress-theme-react-part-2-routes-context/feed/</wfw:commentRss>
			<slash:comments>58</slash:comments>
		
		
			</item>
		<item>
		<title>Let&#8217;s build a WordPress theme with React: Part 1 (Setup)</title>
		<link>https://michaelsoriano.com/wordpress-theme-react-part-1-setup/</link>
					<comments>https://michaelsoriano.com/wordpress-theme-react-part-1-setup/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Tue, 21 May 2019 16:38:24 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[React]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6909</guid>

					<description><![CDATA[<p>It&#8217;s been a while since I worked with WordPress, especially building themes. This time around, I wanted to bring in a bit more modern development experience into the process. I wanted to build a Single Page Application (SPA), with WordPress&#8217; Rest API &#8211; but as a WordPress theme. The problem is, this can be a [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/wordpress-theme-react-part-1-setup/">Let&#8217;s build a WordPress theme with React: Part 1 (Setup)</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>It&#8217;s been a while since I worked with <a href="http://automattic.pxf.io/nL7v4x" rel="nofollow">WordPress</a>, especially building themes. This time around, I wanted to bring in a bit more modern development experience into the process. I wanted to build a Single Page Application (SPA), with WordPress&#8217; Rest API &#8211; but as a WordPress theme. The problem is, this can be a pain to setup. Especially with the build step and all.</p>



<p>I specifically wanted to use <a href="https://reactjs.org"><strong>React</strong></a><strong> </strong>for the front end. React is Facebook&#8217;s product, and per their website: <em>React is a library for building user interfaces</em>. It has a very broad user base and lots of modules available, which makes it ideal for our theme. In conjunction, we&#8217;re using <strong><a href="https://www.npmjs.com/package/create-react-wptheme">create-react-wptheme</a></strong> &#8211; which will make our theme up and running with React in no time. And of course, WP Rest API for the backend.</p>



<p><img decoding="async" width="1348" height="891" src="https://michaelsoriano.com/wp-content/uploads/2020/08/undraw_react_y7wq.png" alt="react" class="wp-image-7237" srcset="https://michaelsoriano.com/wp-content/uploads/2020/08/undraw_react_y7wq.png 1348w, https://michaelsoriano.com/wp-content/uploads/2020/08/undraw_react_y7wq-300x198.png 300w, https://michaelsoriano.com/wp-content/uploads/2020/08/undraw_react_y7wq-1024x677.png 1024w, https://michaelsoriano.com/wp-content/uploads/2020/08/undraw_react_y7wq-768x508.png 768w" sizes="(max-width: 1348px) 100vw, 1348px" /></p>



<p>Note that this tutorial is geared towards PHP or WordPress developers &#8211; who are looking to get started working with Single Page Applications with React. </p>



<p>This will be the first of a series of posts: </p>



<ul class="wp-block-list">
<li><a href="https://michaelsoriano.com/wordpress-theme-react-part-1-setup/">Part 1 &#8211; Setup</a> </li>



<li><a href="https://michaelsoriano.com/wordpress-theme-react-part-2-routes-context/">Part 2 &#8211; Routes + Context</a></li>



<li><a href="https://michaelsoriano.com/lets-build-a-wordpress-theme-with-react-part-3-the-loop/">Part 3 &#8211; The Loop</a></li>
</ul>



<p>The theme we&#8217;re going to build throughout this series is more of a <em>starter</em> theme. We&#8217;re calling it &#8220;barebones&#8221; and it contains just the right amount of functionality for a basic WordPress theme.  </p>



<p>We will need the following to get started: </p>



<ul class="wp-block-list">
<li>nodejs + npm</li>



<li>git bash (or terminal)</li>



<li>local WordPress installation</li>
</ul>



<h3 class="wp-block-heading">create-react-wptheme </h3>



<p>Let&#8217;s talk briefly about create-react-wptheme.  The goal is to get us <em>bootstrapped</em> with a new React based WordPress theme with a few commands. If any of you are familiar with create-react-app, its basically the same functionality &#8211; but for WordPress. One primary difference is that it uses WordPress (not webpack), as the development server. This makes development consolidated in one &#8211; front end and back end. </p>



<p>In addition, since it&#8217;s a WordPress theme, you have access to all the core functions, filters, actions, hooks etc. Also, you can use WordPress&#8217; nonce for authenticated requests. Lastly, if you must use plain PHP &#8211; say only for a specific page, you can still use WordPress&#8217; page templates &#8211; which is very handy.</p>



<p>So with that in mind, let&#8217;s get started. </p>



<p>First, assuming you have a local WordPress installation, go ahead and start a terminal (git bash) in the themes directory. </p>



<figure class="wp-block-image"><img decoding="async" width="600" height="560" src="https://michaelsoriano.com/wp-content/uploads/2019/05/git-bash3.png" alt="" class="wp-image-6955" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/git-bash3.png 600w, https://michaelsoriano.com/wp-content/uploads/2019/05/git-bash3-300x280.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></figure>



<p>In Windows, git bash is a pretty good tool, simply right click and &#8220;Git Bash Here&#8221;. This will launch the terminal, where we can start our installation. Type in the command below:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash line-numbers">npx create-react-wptheme barebones</code></pre>



<p>Note that &#8220;barebones&#8221; is the name of our theme. You can simply replace this with a theme name of your preference.</p>



<figure class="wp-block-image"><img decoding="async" width="500" height="355" src="https://michaelsoriano.com/wp-content/uploads/2019/05/happy-hacking-1.png" alt="npm install" class="wp-image-6921" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/happy-hacking-1.png 500w, https://michaelsoriano.com/wp-content/uploads/2019/05/happy-hacking-1-300x213.png 300w" sizes="(max-width: 500px) 100vw, 500px" /></figure>



<p>Once that&#8217;s done, you will see a message like above. The installation created a root folder, with a &#8220;react-src&#8221; directory inside it. Consider the react-src directory as the most important directory because it holds all of your un-compiled code. From this directory &#8211; we can build the rest. You&#8217;ll see what I mean later.</p>



<p>Note that at this step, our theme is not ready yet.  </p>



<p>See, if you look inside <em>wp-admin</em> &gt; <em>themes</em>, you will see &#8220;barebones&#8221; under the &#8220;Broken Themes&#8221; section.</p>



<figure class="wp-block-image"><img decoding="async" width="549" height="170" src="https://michaelsoriano.com/wp-content/uploads/2019/05/missing-css.png" alt="broken theme" class="wp-image-6923" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/missing-css.png 549w, https://michaelsoriano.com/wp-content/uploads/2019/05/missing-css-300x93.png 300w" sizes="(max-width: 549px) 100vw, 549px" /></figure>



<p>This is because we don&#8217;t have the necessary files (mainly the styles.css) for it to be a valid theme. Note that we also need index.php, so the we can hold the JavaScript and CSS files together. </p>



<h3 class="wp-block-heading">wpstart</h3>



<p>Let&#8217;s go back to our terminal and type the following:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash line-numbers">cd barebones/react-src
npm run wpstart</code></pre>



<p>We&#8217;re going into our theme directory and inside &#8220;react-src&#8221; by using the &#8220;cd&#8221; command, then we run <strong>wpstart</strong>. This will fix the &#8220;Broken Themes&#8221; issue, and if we go back to the browser and go in <em>wp-admin</em> &gt; <em>themes</em> themes, you should be able to see our theme.  </p>



<figure class="wp-block-image"><img decoding="async" width="610" height="395" src="https://michaelsoriano.com/wp-content/uploads/2019/05/wp-admin.png" alt="wp admin" class="wp-image-6925" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/wp-admin.png 610w, https://michaelsoriano.com/wp-content/uploads/2019/05/wp-admin-300x194.png 300w" sizes="(max-width: 610px) 100vw, 610px" /></figure>



<p>Now let&#8217;s activate the theme by clicking &#8220;<strong>Activate</strong>&#8220;. This will tell WordPress to use this theme we just built. Now let&#8217;s go and view our site in the browser. You should see a message </p>



<p>&#8220;<em>Please restart the Nodejs watcher now&#8230;</em> &#8220;</p>



<p>What this means is that we have to run  <strong>wpstart</strong> a second time, for the script finish setting things up. Let&#8217;s go back to git bash and do a &#8220;CTRL +  C&#8221;. Then type in:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash line-numbers">npm run wpstart</code></pre>



<p>Now, once this is done, a new browser tab should have opened automatically and looks like below: </p>



<figure class="wp-block-image"><img decoding="async" width="631" height="508" src="https://michaelsoriano.com/wp-content/uploads/2019/05/react-app.png" alt="react app" class="wp-image-6929" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/react-app.png 631w, https://michaelsoriano.com/wp-content/uploads/2019/05/react-app-300x242.png 300w" sizes="(max-width: 631px) 100vw, 631px" /></figure>



<p>It may not look like much, but this tells us a lot. This page indicates that we&#8217;ve just successfully installed our React theme. This  includes the PHP, CSS and JavaScript files, plus all the resources to run our React application. So well done!</p>



<p><strong>Note: wpstart is for &#8220;dev&#8221; mode.</strong></p>



<p>From this point onward, when you&#8217;re in wpstart mode, (when you do <em>npm run wpstart</em>) that means you are in development mode. What this means is that anytime you change something in the react-src directory, the files will get recompiled and placed in the proper places. Any changes will also cause your browser to refresh &#8211; so you see your changes instantly.</p>



<p><strong>Do Not Edit the files in ROOT</strong></p>



<p>The files in the root folder (outside of react-src), is the compiled version of your code that is needed for WordPress and React to run. You shouldn&#8217;t edit anything in here because as soon as you save files in react-src &#8211; the files in the root will be replaced with the new. <u>So anything you change here will get OVERWRITTEN</u>.</p>



<h3 class="wp-block-heading" id="mce_14">File Structure</h3>



<p>Let&#8217;s take a quick look at at the file structure for it&#8217;s important to know what it is and how create-react-wptheme use it. In a regular WordPress theme, all we really need are the PHP (such as header, footer) and CSS. </p>



<p>In our new theme, it looks something like below: </p>



<figure class="wp-block-image"><img decoding="async" width="650" height="340" src="https://michaelsoriano.com/wp-content/uploads/2019/05/root2.png" alt="root folder" class="wp-image-6956" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/root2.png 650w, https://michaelsoriano.com/wp-content/uploads/2019/05/root2-300x157.png 300w" sizes="(max-width: 650px) 100vw, 650px" /></figure>



<p>As you can see, there is none of the familiar files you would expect in a WP theme. Remember we&#8217;re building an SPA &#8211; which will all be in JavaScript.</p>



<p>As mentioned previously, inside react-src are the uncompiled and &#8220;editable&#8221; version of your code. Everything else (the root and static folder) are the output of what you have in react-src. Take note of that text file that&#8217;s titled <strong>!DO_NOT_EDIT_THESE_FILES!.txt</strong>. Remember what I said about not editing files in the root?</p>



<p><strong>The &#8220;public&#8221; folder</strong></p>



<p>The author of create-react-wptheme saved a special folder for our non-react files called &#8220;public&#8221;. Whatever you add in this folder, gets copied directly to the root. So, things like functions.php, or page templates &#8211; even CSS or JS can be dumped in here &#8211; and it will get copied into the root at compile time.</p>



<figure class="wp-block-image"><img decoding="async" width="650" height="340" src="https://michaelsoriano.com/wp-content/uploads/2019/05/public-folder.png" alt="" class="wp-image-6957" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/public-folder.png 650w, https://michaelsoriano.com/wp-content/uploads/2019/05/public-folder-300x157.png 300w" sizes="(max-width: 650px) 100vw, 650px" /></figure>



<p>Again, this folder can be extremely helpful &#8211; especially for developers who would still like to access core functionality such as hooks, filters, actions etc. </p>



<p>Also, <strong>index.php</strong> &#8211; will only get loaded once, and is the entry way for your React application. The goal is, once loaded, all interactions will be through the REST api. So whatever PHP has produced in <strong>index.php</strong> will stay the same all throughout your application (except PHP page templates).</p>



<p><strong>The &#8220;build&#8221; folder</strong></p>



<p>We haven&#8217;t covered wpbuild yet, but since we talking about the file structure, you will notice a folder called &#8220;<strong>build</strong>&#8220;. This is a special folder that holds the final &#8220;<strong>deployable</strong>&#8221; code. </p>



<p>What that means is, almost like the contents of the &#8220;<strong>root</strong>&#8221; folder, but compressed, minified and optimized for production. Also, it doesn&#8217;t contain any dev files (such as react-src).  </p>



<p>This brings us to the last section: <strong>wpbuild</strong>:</p>



<h3 class="wp-block-heading" id="mce_14">wpbuild</h3>



<p>So let&#8217;s get back to git bash and do CTRL + C.  Type in the following command:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">npm run wpbuild</code></pre>



<p>You will see messaging that looks something like: </p>



<figure class="wp-block-image"><img decoding="async" width="555" height="370" src="https://michaelsoriano.com/wp-content/uploads/2019/05/wpbuild.png" alt="" class="wp-image-6942" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/wpbuild.png 555w, https://michaelsoriano.com/wp-content/uploads/2019/05/wpbuild-300x200.png 300w" sizes="(max-width: 555px) 100vw, 555px" /></figure>



<p>This simply shows files that have been created, optimized and placed in the build folder, <strong>as well as the root</strong>. This means that you see your optimized code right away.</p>



<p>To see how that looks, when you refresh your browser, you will see just a bunch of compressed code like this:</p>



<figure class="wp-block-image"><img decoding="async" width="555" height="420" src="https://michaelsoriano.com/wp-content/uploads/2019/05/compressed-src.png" alt="" class="wp-image-6943" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/compressed-src.png 555w, https://michaelsoriano.com/wp-content/uploads/2019/05/compressed-src-300x227.png 300w" sizes="(max-width: 555px) 100vw, 555px" /></figure>



<p>Your <a href="http://automattic.pxf.io/nL7v4x" rel="nofollow">WordPress</a> theme&#8217;s source code has been flattened, ready for world consumption. Also, take a look at the contents of the root directory:</p>



<figure class="wp-block-image"><img decoding="async" width="650" height="340" src="https://michaelsoriano.com/wp-content/uploads/2019/05/file-structure-wpbuild.png" alt="" class="wp-image-6950" srcset="https://michaelsoriano.com/wp-content/uploads/2019/05/file-structure-wpbuild.png 650w, https://michaelsoriano.com/wp-content/uploads/2019/05/file-structure-wpbuild-300x157.png 300w" sizes="(max-width: 650px) 100vw, 650px" /></figure>



<p>You notice the absence of the file <strong>!DO_NOT_EDIT_THESE_FILES!.txt</strong>. That means, that you&#8217;ve just run wpbuild and its now in &#8220;build&#8221; mode. </p>



<p>When you&#8217;re ready to go back to making some changes, don&#8217;t forget to go back into &#8220;dev&#8221; mode, by running &#8220;<em>npm run wpstart</em>&#8221; in the react-src directory.</p>



<p>And there you have it. We have our React application running as a WordPress theme. I&#8217;ve created a <a href="https://github.com/michaelsoriano/barebones">Github repo</a> for Barebones theme. You can go ahead and fork it for your next project, or stay tuned for more tutorials.</p>
<p>The post <a href="https://michaelsoriano.com/wordpress-theme-react-part-1-setup/">Let&#8217;s build a WordPress theme with React: Part 1 (Setup)</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/wordpress-theme-react-part-1-setup/feed/</wfw:commentRss>
			<slash:comments>25</slash:comments>
		
		
			</item>
		<item>
		<title>How to Build a Company Timeline using Bootstrap and WordPess REST API</title>
		<link>https://michaelsoriano.com/build-company-timeline-bootstrap-wp-rest-api/</link>
					<comments>https://michaelsoriano.com/build-company-timeline-bootstrap-wp-rest-api/#respond</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Fri, 27 Jul 2018 19:08:32 +0000</pubDate>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Bootstrap]]></category>
		<category><![CDATA[REST]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6168</guid>

					<description><![CDATA[<p>So our Company wanted to build a Timeline. One that shows our projects throughout the years, decades even. One that is sleek, modern and responsive. We&#8217;re already running WordPress, and have Bootstrap installed. So this shouldn&#8217;t be too bad. It turns out &#8211; it was a pretty fun project to build. Our in house designers [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/build-company-timeline-bootstrap-wp-rest-api/">How to Build a Company Timeline using Bootstrap and WordPess REST API</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>So our Company wanted to build a Timeline. One that shows our projects throughout the years, decades even. One that is sleek, modern and responsive. We&#8217;re already running WordPress, and have Bootstrap installed. So this shouldn&#8217;t be too bad. It turns out &#8211; it was a pretty fun project to build.</p>



<p>Our in house designers are responsible for the design of this page. It&#8217;s a little bit of Facebook&#8217;s original timeline layout &#8211; but a lot simpler and minimalist. Here is a preview of how it looks:</p>



<p><img decoding="async" width="875" height="506" class="alignnone size-full wp-image-6685" style="border: 1px solid #ededed;" src="https://michaelsoriano.com/wp-content/uploads/2017/10/timeline.gif" alt=""><br></p>



<p>In a nutshell, this is what we&#8217;re going to accomplish: We&#8217;re going to use custom post types (CPT) for each entry in the Timeline. We&#8217;re grabbing them via JavaScript &#8211; using the WP Rest API as the endpoint. We&#8217;re also using Boostrap&#8217;s grid system &#8211; so our timeline behaves well in mobile.</p>



<p>We are going to build everything as part of the theme. For more advanced users &#8211; you can also build it as a plugin.</p>



<p>Note that you have to be familiar with WordPress, PHP and Front end to follow. There is no download for this &#8211; you simply have to follow along.</p>



<p>Ready to get started? Let&#8217;s begin:</p>



<h3 class="wp-block-heading">The Back-End</h3>



<p>First off, let&#8217;s take care of the data. We need to register the CPT with WordPress and make sure we have the right custom fields. Actually, we only have one custom field necessary &#8211; and that is the year. The year is what the timeline is sorted by (newest to oldest).</p>



<p>Open up <strong>functions.php</strong> in your theme. First let&#8217;s add the CPT initialization.</p>



<pre class="wp-block-code"><code lang="php" class="language-php">function registerTimelineCPT() {
        $labels = array(
            'name' =&gt; __( 'Timeline' ),
            'singular_name' =&gt; __( 'Timeline' ),
            'add_new_item'       =&gt; __( 'Add New Timeline'),
            'new_item'           =&gt; __( 'Timeline'),
            'edit_item'          =&gt; __( 'Edit Timeline'),
            'view_item'          =&gt; __( 'View Timeline'),
            'all_items'          =&gt; __( 'View All'),
        );
        register_post_type( 'timeline',
            array(
                'labels' =&gt; $labels,
                'public' =&gt; true,
                'has_archive' =&gt; false,
                'rewrite' =&gt; false,
                'publicly_queriable' =&gt; true,
                'exclude_from_search' =&gt; true,
                'show_ui' =&gt; true,
                'show_in_nav_menus' =&gt; false,
                'show_in_menu' =&gt; true,
                'show_in_admin_bar' =&gt; false,
                'menu_icon' =&gt; 'dashicons-backup',
                'show_in_rest' =&gt; true,
                'public' =&gt; false, //removes the "permalink"
                'supports' =&gt; array(
                    'title',
                    'excerpt',
                    'thumbnail',
                    'custom-fields'
                )
            )
        );
        //REMOVES COMMENTS
        remove_post_type_support( 'timeline', 'comments' );
}
add_action( 'init', 'registerTimelineCPT' );</code></pre>



<p>Above, we&#8217;re simply creating our CPT called &#8220;Timeline&#8221;. We&#8217;re setting up the labels, what it supports and what it doesn&#8217;t support. Upon logging in you should see a &#8220;<strong>Timeline</strong>&#8221; in your admin area.</p>



<p>Now for the&nbsp; custom fields &#8211; you can easily add this the default way according to <a href="https://codex.wordpress.org/Custom_Fields">WordPress</a>. In my case, I wanted to make it easier for the users to update &#8211; so I&#8217;m using this plugin called &#8220;<a href="https://metabox.io">Meta Box</a>&#8220;. </p>



<p>Our custom field is now easier to set up and become much cleaner to the users.<br>If you have MetaBox installed, adding the field is as simple as below. This goes into your <strong>functions.php</strong>.</p>



<pre class="wp-block-code"><code lang="php" class="language-php">function createMetaBoxes($meta_boxes ){
	$prefix = 'tl_';
	$meta_boxes[] = array(
		'id' =&gt; 'timeline_metabox',
		'title' =&gt; esc_html__( 'Other', $prefix ),
		'post_types' =&gt; array( 'timeline' ),
		'context'    =&gt; 'normal',
		'priority'   =&gt; 'low',
		'autosave'   =&gt; true,
		'fields'     =&gt; array(
			array(
				'name' =&gt; esc_html__( 'Timeline',  $prefix  ),
				'id'   =&gt; 'timeline_year',
				'label_description' =&gt; esc_html__( 'Year', $prefix ),
				'type' =&gt; 'range',
				'min'  =&gt; '1930',
				'max'  =&gt; date("Y"),
				'step' =&gt; 1,
				'std'  =&gt; date("Y"),
			)
		)
	);
	return $meta_boxes;
}
add_filter( 'rwmb_meta_boxes', 'createMetaBoxes' );</code></pre>



<p>Now if you go to the Timeline page, you should see our nice range slider:</p>



<p><img decoding="async" width="545" height="449" class="alignnone size-full wp-image-6705" src="https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-cfield.png" alt="timeline - cpt" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-cfield.png 545w, https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-cfield-300x247.png 300w" sizes="(max-width: 545px) 100vw, 545px" /></p>



<p>We&#8217;re also using the following default WordPress fields:</p>



<ul class="wp-block-list">
<li>Title</li>



<li>Excerpt</li>



<li>Featured Image</li>
</ul>



<p>So as you&#8217;re following along, go ahead and add several timelines and make sure these fields are filled out.</p>



<h3 class="wp-block-heading">REST Endpoint</h3>



<p>Before we can call our Timelines through REST, we have to do some setup. Still in <strong>functions.php</strong>, add the code below:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">function restProperties(){
	register_rest_field( 'timeline',
		'timeline_year',
		array(
		   'get_callback' =&gt; 'registerRestCb',
		   'update_callback' =&gt; null,
		   'schema'          =&gt; null,
		)
	 );
	function registerRestCb($object, $field_name, $request){
		return get_post_meta( $object[ 'id' ], $field_name, true );
	}
}
add_action( 'rest_api_init', 'restProperties');</code></pre>



<p>So the above makes the &#8216;timeline&#8217; available as and endpoint in REST. Also, we&#8217;re adding the &#8216;timeline_year&#8217; as a property in the response. To find out more about WP REST API, check their <a href="https://developer.wordpress.org/rest-api/">documentation</a>.</p>



<p>Now, when you hit the endpoint: YOURURL +&#8217;<strong>/wp-json/wp/v2/timeline?_embed&amp;per_page=100</strong>&#8216;, you should now see data as a JSON string. This is enough for us to work with in our Front End. Let&#8217;s go do that now.</p>



<h3 class="wp-block-heading">The Front-End</h3>



<p>Before we continue, I forgot to mention the libraries that we need to work with:</p>



<ul class="wp-block-list">
<li>jQuery</li>



<li>Bootstrap</li>



<li>Handlebars</li>
</ul>



<h4 class="wp-block-heading">Markup</h4>



<p>I&#8217;m going to add the markup first (the handlebar templates), then we&#8217;ll move on to the logic.</p>



<p>This is the <span style="text-decoration: underline;">main template</span>:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;script id="timeline-template" type="text/x-handlebars-template"&gt;
    {{#each this}}
    &lt;div class="decade-wrap" id="decade-{{decade}}"&gt;            
    &lt;h1&gt;{{decade}}s&lt;/h1&gt;
    {{#each @this}}                    
        &lt;div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 timeline-item timeline-index-{{@index}} timeline-{{leftOrRight @index}}"&gt;
            &lt;div class="timeline-year"&gt;{{year}}&lt;/div&gt;
            &lt;div class="timeline-inner-wrap col-lg-8 col-md-8 col-sm-8 col-lg-12 {{pull @index}}"&gt;                
                &lt;div class="timeline-thumbnail" style="background:url('{{img}}') no-repeat #ccc"&gt;                 
                &lt;/div&gt; 
                &lt;div class="timeline-title"&gt;{{title}}&lt;/div&gt;
                &lt;div class="timeline-excerpt"&gt;{{{excerpt}}}&lt;/div&gt;
            &lt;/div&gt;
        &lt;/div&gt;
        {{{closeWrap @index}}}
    {{/each}}
    &lt;/div&gt;
    {{/each}}
&lt;/script&gt;</code></pre>



<p>As you can see, we&#8217;re using the Bootstrap col classes to make each item responsive. We&#8217;re also using pull classes &#8211; so the alternate item will be pulled to the left.</p>



<p>The <span style="text-decoration: underline;">decades scroller</span>:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;script id="timeline-decades-template" type="text/x-handlebars-template"&gt; 
{{#each this}}
    &lt;div class="timeline-decades-link-item decade-{{decade}} {{showingOrNot @index}}"&gt;
            &lt;a href="#decade-{{decade}}"&gt;{{decade}}s&lt;/a&gt;
    &lt;/div&gt;
{{/each}}
&lt;/script&gt;</code></pre>



<p>Nothing fancy here, just a list of decades that is clickable.</p>



<p>Lastly, let&#8217;s build the <span style="text-decoration: underline;">wrapper</span>:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;div class="timeline-decade-links-wrapper"&gt;
  &lt;div class="timeline-decade-links"&gt;
       &lt;div class="getting-items"&gt;Getting Items&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class="timeline-wrapper"&gt;&lt;/div&gt; 
&lt;div class="show-more-wrap"&gt;
   &lt;a href="#"&gt;&lt;img src="showmore.png"&gt;&lt;/a&gt;
&lt;/div&gt;</code></pre>



<p>The above markup simply holds the timelines together. It also has the text &#8220;Getting Items&#8221; &#8211; which acts as our loader &#8211; until our AJAX call completes. Also, we have a &#8220;show more&#8221; button &#8211; so that when clicked &#8211; the rest of the items appear in the bottom.</p>



<p>So the above is our HTML. Now we need JavaScript, which is described below.</p>



<h3 class="wp-block-heading">Getting and Grouping the Items</h3>



<p>This is where we pull the data from our REST endpoint, and pass it on to the handlebars templates that we&#8217;ve created. We also need&nbsp;additional logic &#8211; specifically grouping the decades together to build the scroller.</p>



<p>Let&#8217;s grab our items via .ajax():</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">$(document).ready(function(){
	$.ajax({
		url : '/wp-json/wp/v2/timeline?_embed&amp;per_page=100',
		success : function(data){
                        console.log(JSON.parse(data));
			//TODO :compileTemplates();
			//TODO: bindDecadeScroller();
		},
		error : function(data){
			console.log('Error in fetching timeline...')
		}
	})
});</code></pre>



<p>All things are happening inside the document ready handler. Now if you refresh your browser, you shall see our data in a parsed JSON object.<br><img decoding="async" width="752" height="503" class="alignnone size-full wp-image-6723" src="https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-object.png" alt="timeline object" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-object.png 752w, https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-object-300x201.png 300w" sizes="(max-width: 752px) 100vw, 752px" /></p>



<p>Now that we have our objects in place, remove the console.log() line that we have. We have 2 TODOS: functions that we haven&#8217;t built yet, namely&nbsp;<strong>compileTemplates</strong>() and&nbsp;<strong>bindDecadeScroller</strong>(). You can guess what both of them do.</p>



<p>Let&#8217;s add the first function&nbsp;<strong>compileTemplates()</strong>:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function compileTemplates(data){
	var parsed = JSON.parse(data);
	if(parsed.length &gt; 0){
		var obj = buildTimeline(parsed);
		var source  = $("#timeline-template").html();
		var source2 = $("#timeline-decades-template").html();
		var template = Handlebars.compile(source);
		var template2 =  Handlebars.compile(source2);
		$('.timeline-decade-links').html(template2(obj));
		$('.timeline-wrapper').html(template(obj));
	}
}</code></pre>



<p>The above simply compiles the JSON data and hands it over to our templates. This alone should get our views going. But don&#8217;t refresh the browser yet. There are plenty of logic that still needs to happen.</p>



<p>Notice the new function in line 4 called &#8220;<strong>buildTimeline()</strong>&#8220;.&nbsp; On top of that, we have Handlebar helpers that we haven&#8217;t registered &#8211; so the browser will actually throw a fit. This will be covered in the section below &#8220;<strong>View Helpers</strong>&#8220;.</p>



<p>Let&#8217;s build the function called&nbsp;<strong>buildTimeline()</strong>:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function buildTimeline(data){
    function comp(a, b){
        return b - a;
    }
    function compYear(a,b) {
        if (b.year &lt; a.year)
            return -1;
        if (b.year &gt; a.year)
            return 1;
        return 0;
    }
    function grabImg(el){
        var src = '';
        if(el._embedded){
            if(el._embedded['wp:featuredmedia']){
                src = el._embedded['wp:featuredmedia'][0]['source_url'];
            }
        }
        return src;
    }
    $.each(data, function(){
        $(this)[0].timeline_year = parseInt($(this)[0].timeline_year);
    })
    //add decade:
    $.each(data, function(){
        var year = $(this)[0].timeline_year;
        $(this)[0].timeline_year_decade = Math.floor(year / 10) * 10;
    })
    //group decades:
    var decades = [];
    $.each(data, function(){
        decades.push($(this)[0].timeline_year_decade);
    })
    var uniqueDecades = [];
    $.each(decades, function(i, el){
        if($.inArray(el, uniqueDecades) === -1) uniqueDecades.push(el);
    });
    decades = uniqueDecades.sort(comp);
    var clean = Array();
    var final = Array();
    $.each(data, function(i, el){
        var obj = {};
        obj.id = el.id;
        obj.img = grabImg(el);
        obj.title = el.title.rendered;
        obj.excerpt = el.excerpt.rendered;
        obj.year = el.timeline_year;
        obj.year_decade = el.timeline_year_decade;
        clean.push(obj);
    });
    clean = clean.sort(compYear);
    $.each(decades,function(i,el){
        var key = i;
        final[key] = Array();
        $.each(clean,function(x,xel){
            final[key]['decade'] = el;
            if(xel.year_decade == el){
                final[key].push(xel);
            }
        })
    })
    return final;
}</code></pre>



<p>Okay this is the meat of our logic. We&#8217;re trying to grab all of the years in our timelines. And from each of those years, we need to calculate the decade, take out the duplicates and stuff them back to a final array, grouped by decade.</p>



<p>In lines 31-34 is where we calculate the decade, then stuffing it to a new property called &#8220;<strong>timeline_year_decade</strong>&#8220;. Then we&#8217;re doing a couple more loops to remove duplicates, sort and create a clean &#8220;<strong>decades</strong>&#8221; array &#8211; which we need for our final loop in lines 66-75.</p>



<p>Refresh your browser and see what our &#8220;<strong>final</strong>&#8221; array looks like.</p>



<p><img decoding="async" width="780" height="615" class="alignnone size-full wp-image-6729" src="https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-object2.png" alt="timeline - object grouped" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-object2.png 780w, https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-object2-300x237.png 300w, https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-object2-768x606.png 768w" sizes="(max-width: 780px) 100vw, 780px" /></p>



<p>Now we our&nbsp;<strong>compileTemplates() </strong>is done, let&#8217;s go and register our <strong>helpers</strong> and do some <strong>CSS</strong>.</p>



<h3 class="wp-block-heading"><strong>View Helpers</strong></h3>



<p>Now we have to do add more scripting to determine additional classes that makes our timeline look the way it does.</p>



<p>In case you haven&#8217;t noticed, our templates are sprinkled with helpers for handlebars. Let&#8217;s register those helpers now.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">Handlebars.registerHelper('leftOrRight', function(index) {
	return index %2 == 0 ? 'left' : 'right';
});
Handlebars.registerHelper('closeWrap', function(index) {
   return (index+1) %2 == 0 ? '&lt;div class="clearfix"&gt;&lt;/div&gt;' : '';
});
Handlebars.registerHelper('pull', function(index) {
   return index %2 == 0 ? '' : 'col-lg-push-4 col-md-push-4 col-sm-push-4';
});
Handlebars.registerHelper('showingOrNot', function(index) {
	if(index == 0){
		return 'showing';
	}
});</code></pre>



<p>The above are view helpers &#8211; that cooperates with the HTML templates that we just built. For instance, the &#8220;leftOrRight&#8221; helper &#8211; determines if a class of &#8220;left&#8221; or &#8220;right&#8221; is to be added. Below are the images for that:</p>



<p>Left Line:</p>



<p><br><img decoding="async" width="142" height="16" class="alignnone size-full wp-image-6713" src="https://michaelsoriano.com/wp-content/uploads/2018/07/left_line.png" alt="left line"><br></p>



<p>Right Line:</p>



<p><br><img decoding="async" width="141" height="16" class="alignnone size-full wp-image-6714" src="https://michaelsoriano.com/wp-content/uploads/2018/07/right_line.png" alt=""><br></p>



<p>Arrow up:<br></p>



<p><img decoding="async" width="12" height="8" class="alignnone size-full wp-image-6730" src="https://michaelsoriano.com/wp-content/uploads/2018/07/arrow-up.png" alt=""><br></p>



<p>Vertical Line:</p>



<p><br><img decoding="async" width="1" height="186" class="alignnone size-full wp-image-6734" src="https://michaelsoriano.com/wp-content/uploads/2018/07/vertical_line.png" alt=""><br></p>



<h3 class="wp-block-heading">The Styles</h3>



<p>Finally, the styles that make our timeline look good. I&#8217;m not going to walk through what each style does. I&#8217;m just going to add this as a reference for you to plugin. You might have a different style depending on your preference.</p>



<pre class="wp-block-code"><code lang="css" class="language-css">.timeline-wrapper {
    position:relative;
    z-index: 99;
}
.decade-wrap {
    overflow:hidden;
    clear:both;
    display:block;
    background:url('vertical_line.png') #fff repeat-y;
    background-position-x: center;
}
.decade-wrap:first-child {
    padding-top: 40px;
}
.decade-wrap:last-child{
    margin-bottom: 75px;
}
.decade-wrap h1 {
    text-align: center;
    background:#fff;
    padding:25px 0 35px;
    font-size:45px;
    color: #0077C8;
}
.timeline-thumbnail {
    background-position-x: center !important;
    background-position-y: center !important;
    background-size: cover !important;
    height:319px;
}
.timeline-item,
.timeline-inner-wrap {
    padding-left:0;
    padding-right:0;
}
.timeline-left {
    background:url('left_line.png') no-repeat right center;
    margin-left: 8px;
}
.timeline-right {
     margin-top: 100px;
    background:url('right_line.png') no-repeat left center;
    margin-left: -15px;
}
.timeline-inner-wrap {
    padding-top: 25px;
}
.timeline-year {
    position: absolute;
    top: 39%;
    font-size:30px;
    font-weight: 500;
    color: #0077C8;
}
.timeline-right .timeline-year {
    padding-left: 35px;
}
.timeline-left .timeline-year {
    right:0;
    padding-right: 34px;
}
.timeline-title {
    font-size: 19px;
    font-weight: 500;
    color: #000;
    padding-top: 15px;
    padding-bottom: 10px;
}
.timeline-decade-links {
    background:#ececec;
    min-height: 60px;
    display: flex;
}
.timeline-decades-link-item {
    width: 100px;
    margin: 0 auto;
    text-align: center;
    font-size: 18px;
    padding-top: 18px;
    height: 60px;
}
.timeline-decades-link-item a:hover,
.timeline-decades-link-item a:focus{
    text-decoration:none;
}
.timeline-decades-link-item.showing {
    background:url('arrow-up.png') transparent no-repeat center bottom;
}
.timeline-decade-links-wrapper {
    overflow: hidden;
}
.timeline-decade-links-wrapper.fixed {
    position: fixed;
    top: 0px;
    z-index: 110;
    left:0;
    width:100%;
}
.admin-bar .timeline-decade-links-wrapper.fixed {
    top:32px;
}
@media(max-width:1199px){
    .timeline-thumbnail {
        height:253px;
    }
    .timeline-item {
        background-position-y: 33%;
    }
    .timeline-year{
        top: 21%;
    }
}
@media(max-width:991px){
    .timeline-thumbnail {
        height:190px;
    }
    .timeline-item {
        background-position-y: 28%;
    }
    .timeline-year{
        top: 18%;
        font-size: 23px;
    }
    .decade-wrap h1 {
        padding: 14px 0 24px;
        font-size: 31px;
    }
}
@media(max-width:768px){
    .timeline-thumbnail {
        height:354px;
        width:410px;
    }
    .decade-wrap {
        background:none;
    }
    .decade-wrap:first-child {
        padding-top:0;
    }
    .decade-wrap h1 {
        padding: 0px 0px 0px 0px;
    }
    .timeline-right {
        margin-top: 0;
    }
    .timeline-item {
        background:#fff;
        margin-left: 0 !important;
        margin-right:0 !important;
    }
    .timeline-year {
        position: relative;
        padding-left: 0 !important;
        padding-right:0 !important;
    }
    .timeline-decade-links {
        display: none;
    }
}
@media(max-width:500px){
    .timeline-thumbnail {
        height:302px;
        width:auto;
    }
}
@media(max-width:375px){
    .timeline-thumbnail {
        height:242px;
    }
}</code></pre>



<p>&nbsp;<br>After our helpers apply the classes, our CSS and images in place &#8211; Bootstrap will take care of the rest. If you refresh, you should see your timeline. Inspect and you see our classes applied.</p>



<p><img decoding="async" width="1006" height="591" class="alignnone size-full wp-image-6718" src="https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-classes.png" alt="timeline classes" srcset="https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-classes.png 1006w, https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-classes-300x176.png 300w, https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-classes-768x451.png 768w" sizes="(max-width: 1006px) 100vw, 1006px" /></p>



<p>Finally, let&#8217;s go ahead and bind that scroller:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function bindDecadeScroller(){
	 $('.timeline-decades-link-item a').on('click',function(){
		var id = $(this).attr('href');
		var offset = ($(id).offset().top - 150) ;
		$('html, body').stop().animate({
			scrollTop: offset
		}, 1000);
		return false;
	})
}</code></pre>



<p>This should have a smooth animating effect when you click on the decades on the scroller. Note that our timelines are grouped by decades, encapsulated in a DIV with the ID &#8211; of the decade. So when our scroller is cicked &#8211; it has the ID of the DIV in it&#8217;s href attribute. </p>



<p>So technically, even without our animation &#8211; it will know where to focus naturally.</p>



<p><img decoding="async" width="636" height="673" class="alignnone size-full wp-image-6737" src="https://michaelsoriano.com/wp-content/uploads/2018/07/timeline-responsive.gif" alt="timeline - responsive"></p>



<p>We&#8217;re using .animate() to make that jump smoother. Check jQuery&#8217;s <a href="http://api.jquery.com/animate/">documentation</a> on .animate for more information.</p>



<h3 class="wp-block-heading">Conclusion</h3>



<p>And there you have it. We&#8217;ve just build a pretty cool timeline &#8211; grouped by decades, with a scroller that focuses on the decade when clicked. This is also responsive &#8211; so it looks real good in a mobile device. </p>



<p>Note that this is a pretty basic timeline &#8211; which you can greatly enhance by adding other things. For example, you can add a modal for more details for each of the item. Or even multiple images per item &#8211; one that you can scroll left to right like a slideshow. There are many possibilities.</p>



<p>For the live page, check out the Parsons <a href="https://www.parsons.com/about/timeline/">timeline</a> page.&nbsp;I hope you enjoyed this tutorial. Leave your comments below.</p>
<p>The post <a href="https://michaelsoriano.com/build-company-timeline-bootstrap-wp-rest-api/">How to Build a Company Timeline using Bootstrap and WordPess REST API</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/build-company-timeline-bootstrap-wp-rest-api/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>New WordPress Starter Theme using VueJS</title>
		<link>https://michaelsoriano.com/wordpress-starter-theme-using-vuejs/</link>
					<comments>https://michaelsoriano.com/wordpress-starter-theme-using-vuejs/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Sat, 17 Feb 2018 19:21:18 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[vue]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6447</guid>

					<description><![CDATA[<p>I&#8217;ve been building WordPress themes for quite some time now. And with the advent of front-end frameworks and WP&#8217;s REST API, I thought it would be a good combination to build one that uses both. The benefits would be that the site&#8217;s user experience would be lightning fast. There wouldn&#8217;t be server page loads (except [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/wordpress-starter-theme-using-vuejs/">New WordPress Starter Theme using VueJS</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;ve been building WordPress themes for quite some time now. And with the advent of front-end frameworks and WP&#8217;s REST API, I thought it would be a good combination to build one that uses both. The benefits would be that the site&#8217;s user experience would be lightning fast. There wouldn&#8217;t be server page loads (except for the first one). </p>



<p>So all subsequent navigation will be done in the client side. This results to a smoother and better user experience.</p>



<p class="btn"><a href="https://github.com/michaelsoriano/wp-vue-starter">View in Github</a></p>



<p>I wanted to build several themes, but would like a base theme to start with. Enter <strong>wp-vue-starter. </strong>A starter theme that is built on a popular framework called Vue, and WP&#8217;s REST API in the background.</p>



<p><br><img decoding="async" width="850" height="332" class="alignnone size-full wp-image-6451" src="https://michaelsoriano.com/wp-content/uploads/2018/01/wp-vue.jpg" alt="wp vue logos" srcset="https://michaelsoriano.com/wp-content/uploads/2018/01/wp-vue.jpg 850w, https://michaelsoriano.com/wp-content/uploads/2018/01/wp-vue-300x117.jpg 300w, https://michaelsoriano.com/wp-content/uploads/2018/01/wp-vue-768x300.jpg 768w" sizes="(max-width: 850px) 100vw, 850px" /></p>



<p>Note that since all of the rendering is done in the client, SEO is not going to be available. But for sites that SEO will not matter, I think this is a good choice. Let me explain the theme design and structure and maybe you can use the theme in your next project.</p>



<h3 class="wp-block-heading">Traditional Blog Design</h3>



<p>If you do a search on WordPress Theme and Vue, there have been many attempts on it. This however, is slightly different. First of all, is the design. It uses the traditional blog design that many of us WordPress users have grown to like.</p>



<p>Here is a screenshot of the homepage:</p>



<p><img decoding="async" width="850" height="960" class="alignnone size-full wp-image-6448" src="https://michaelsoriano.com/wp-content/uploads/2018/01/home-page.png" alt="home" srcset="https://michaelsoriano.com/wp-content/uploads/2018/01/home-page.png 850w, https://michaelsoriano.com/wp-content/uploads/2018/01/home-page-266x300.png 266w, https://michaelsoriano.com/wp-content/uploads/2018/01/home-page-768x867.png 768w" sizes="(max-width: 850px) 100vw, 850px" /><br></p>



<p>As you can see, it has a &#8220;static&#8221; page that is called &#8220;home&#8221;. There is a big area (jumbotron) for your carousel or hero image, while the latest posts are directly below it. The CSS framework is Bootstrap (version 4). So editing the grid and elements is familiar to many. A sidebar is built in &#8211; which is pretty standard to most sites.</p>



<p>What is a site without &#8220;Search&#8221;. That of course is also included. A search form is in the header, and is a component called &#8220;search-form&#8221;. So this component can be used in the sidebar, footer &#8211; where ever you want the form to be.</p>



<p>The search results look look like below:</p>



<p><img decoding="async" width="850" height="1116" class="alignnone size-full wp-image-6449" src="https://michaelsoriano.com/wp-content/uploads/2018/01/search-results.png" alt="search template" srcset="https://michaelsoriano.com/wp-content/uploads/2018/01/search-results.png 850w, https://michaelsoriano.com/wp-content/uploads/2018/01/search-results-228x300.png 228w, https://michaelsoriano.com/wp-content/uploads/2018/01/search-results-780x1024.png 780w, https://michaelsoriano.com/wp-content/uploads/2018/01/search-results-768x1008.png 768w" sizes="(max-width: 850px) 100vw, 850px" /><br>Also notice the paging. The paging system is inside a component called &#8220;the-loop&#8221;. For many of us theme developers, the &#8220;Loop&#8221; is the basis of a template inside a theme. So I wanted to keep the same concept here. So you will see the &#8220;archive&#8221; and &#8220;search&#8221; is basically using &#8220;the-loop&#8221; component, because it shares the same properties.</p>



<h3 class="wp-block-heading">Single, Page and Comments Form</h3>



<p>The &#8220;single&#8221; post page is also a Vue component. This accessed using the slug:</p>



<p><strong>/post/post-name</strong></p>



<p>The &#8220;page&#8221; page is another component, and can be accessed by:</p>



<p><strong>/page/page-name</strong></p>



<p>So the urls are not exactly as the traditional WordPress urls, but is quite clean in my opinion. So you need to update your permalink structure in WordPress to <strong>/post/%postname%/:</strong></p>



<p><img decoding="async" width="959" height="259" class="alignnone size-full wp-image-6467" src="https://michaelsoriano.com/wp-content/uploads/2018/02/permalink.png" alt="permalink" srcset="https://michaelsoriano.com/wp-content/uploads/2018/02/permalink.png 959w, https://michaelsoriano.com/wp-content/uploads/2018/02/permalink-300x81.png 300w, https://michaelsoriano.com/wp-content/uploads/2018/02/permalink-768x207.png 768w" sizes="(max-width: 959px) 100vw, 959px" /></p>



<p>So you can still access most of the admin functionality such as viewing pages, posts and previewing.</p>



<p>Below is an example of the single page.</p>



<p><img decoding="async" width="850" height="2231" class="alignnone size-full wp-image-6450" src="https://michaelsoriano.com/wp-content/uploads/2018/01/single.png" alt="single template" srcset="https://michaelsoriano.com/wp-content/uploads/2018/01/single.png 732w, https://michaelsoriano.com/wp-content/uploads/2018/01/single-114x300.png 114w, https://michaelsoriano.com/wp-content/uploads/2018/01/single-390x1024.png 390w, https://michaelsoriano.com/wp-content/uploads/2018/01/single-768x2016.png 768w, https://michaelsoriano.com/wp-content/uploads/2018/01/single-585x1536.png 585w, https://michaelsoriano.com/wp-content/uploads/2018/01/single-780x2048.png 780w" sizes="(max-width: 850px) 100vw, 850px" /><br>In addition, to the content &#8211; is the comments. This theme is built with the comment responses and the form in it. It is pretty basic in design &#8211; very &#8220;Bootstrapy&#8221;. But again, this is a starter theme &#8211; so what do you expect.</p>



<h3 class="wp-block-heading">Theme Structure</h3>



<p>So if you&#8217;re going to use <strong>wp-vue-starter, </strong>chances are, you&#8217;re going to edit it. So let&#8217;s go over the structure briefly. Note that you need to know WordPress and Vue a little bit to dive into this.<br>Everything goes in through <strong>index.php. </strong></p>



<p>This is where your entire HTML wrapper is. From the opening HTML tag, header and footer is inside here. You will also see that all of the templates are included in this page as &#8220;template&#8221; tags.</p>



<p><img decoding="async" width="565" height="416" class="alignnone size-full wp-image-6469" src="https://michaelsoriano.com/wp-content/uploads/2018/02/indexphp.png" alt="index" srcset="https://michaelsoriano.com/wp-content/uploads/2018/02/indexphp.png 565w, https://michaelsoriano.com/wp-content/uploads/2018/02/indexphp-300x221.png 300w" sizes="(max-width: 565px) 100vw, 565px" /></p>



<p>This is also where the DIV called &#8220;<strong>app</strong>&#8221; is &#8211; so Vue is inserting the entire application into this DIV. The <strong>styles.css</strong> in the root is nothing but a marker. It just tells WordPress about the theme name and such.</p>



<p>There are actually no styles in here. Instead, the styles go into <strong>/css/dist/main.css</strong> The <strong>main.js </strong>is where all of the JavaScript logic is. This is where the components are declared, all of the methods as well the routing. If you want to change Vue or JS logic, this is the right file. Below shows a sample of the route mapping system.</p>



<p><img decoding="async" width="654" height="720" class="alignnone size-full wp-image-6471" src="https://michaelsoriano.com/wp-content/uploads/2018/02/routes.png" alt="routes" srcset="https://michaelsoriano.com/wp-content/uploads/2018/02/routes.png 654w, https://michaelsoriano.com/wp-content/uploads/2018/02/routes-273x300.png 273w" sizes="(max-width: 654px) 100vw, 654px" /></p>



<p>Normal WordPress functions go inside the <strong>functions.php</strong>. This is where you will see modifying REST responses and such. Note that by default, the theme is allowing anonymous comments &#8211; so you might want to change this.</p>



<p>Lastly, inside the &#8220;templates&#8221; folder &#8211; are the components. They&#8217;re PHP files, but there&#8217;s no PHP logic in them. I just left it like that for consistency &#8211; and just in case you want to add some PHP in it, you can. The files resemble a traditional WordPress theme. Like 404, page, single, search etc.</p>



<p><img decoding="async" width="515" height="550" class="alignnone size-full wp-image-6472" src="https://michaelsoriano.com/wp-content/uploads/2018/02/templates.png" alt="templates" srcset="https://michaelsoriano.com/wp-content/uploads/2018/02/templates.png 515w, https://michaelsoriano.com/wp-content/uploads/2018/02/templates-281x300.png 281w" sizes="(max-width: 515px) 100vw, 515px" /></p>



<p>Lastly, the &#8220;partials&#8221; are the files with the underscore prefix. So this the _header, _footer, _sidebar. Note that this &#8220;header&#8221; is the html header &#8211; not the &#8220;&lt;head>&#8221;.</p>



<h3 class="wp-block-heading">Installation</h3>



<p>Installation is the same as any other theme. Simply upload and activate (don&#8217;t forget to update the permalinks). You can also use SASS &#8211; for CSS preprocessing. This is included by default, and is the best way to edit CSS. The source files are inside /src and output is /dist.</p>



<p>Gulp is the default build tool, so you can run</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"><strong>npm i -D gulp gulp-sass gulp-sourcemaps gulp-clean-css</strong></code></pre>



<p>For the SASS compiler and CSS clean up.</p>



<p>The theme is under MIT license, and is available in <a href="https://github.com/michaelsoriano/wp-vue-starter">GithHub</a>. I will be adding more features such as additional templates etc., so stay tuned.</p>
<p>The post <a href="https://michaelsoriano.com/wordpress-starter-theme-using-vuejs/">New WordPress Starter Theme using VueJS</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/wordpress-starter-theme-using-vuejs/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Convert WordPress default Gallery into a simple Carousel without a plugin</title>
		<link>https://michaelsoriano.com/convert-wordpress-default-gallery-into-a-simple-carousel-without-a-plugin/</link>
					<comments>https://michaelsoriano.com/convert-wordpress-default-gallery-into-a-simple-carousel-without-a-plugin/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Sat, 02 Sep 2017 17:57:04 +0000</pubDate>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6300</guid>

					<description><![CDATA[<p>I had the fun task to turn the default WordPress gallery into a carousel. Our users didn&#8217;t really like the grid of images, that WordPress ships with. Instead, our designers came up with something like below: It&#8217;s basically a carousel, with the caption in a grey area in the side, along with control buttons in [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/convert-wordpress-default-gallery-into-a-simple-carousel-without-a-plugin/">Convert WordPress default Gallery into a simple Carousel without a plugin</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I had the fun task to turn the default WordPress gallery into a carousel. Our users didn&#8217;t really like the grid of images, that WordPress ships with. Instead, our designers came up with something like below:</p>



<p><br><img decoding="async" width="661" height="412" class="alignnone size-full wp-image-6385" src="https://michaelsoriano.com/wp-content/uploads/2017/09/carousel.png" alt="" srcset="https://michaelsoriano.com/wp-content/uploads/2017/09/carousel.png 661w, https://michaelsoriano.com/wp-content/uploads/2017/09/carousel-300x187.png 300w" sizes="(max-width: 661px) 100vw, 661px" /><br></p>



<p>It&#8217;s basically a carousel, with the caption in a grey area in the side, along with control buttons in the bottom. When clicked, the next image is shown.</p>



<p>At first, I thought of using a plugin, which would&#8217;ve been fine. Except this would&#8217;ve added some level of training on how to use carousel plugins. Most of which are quite complicated to use. Besides, our users are already familiar with using the default WordPress gallery option. They just want to change the way it looks!</p>



<p>So the solution was to use a little bit of JavaScript and CSS. Note that this requires jQuery, Bootstrap for the grid, as well as Handlebars for templating.</p>



<p>Let&#8217;s begin:</p>



<p>First, let&#8217;s add a gallery to our page.<br><img decoding="async" width="759" height="549" class="alignnone size-full wp-image-6308" src="https://michaelsoriano.com/wp-content/uploads/2017/11/insert-gallery.png" alt="Insert a Gallery" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/insert-gallery.png 759w, https://michaelsoriano.com/wp-content/uploads/2017/11/insert-gallery-300x217.png 300w" sizes="(max-width: 759px) 100vw, 759px" /><br>Make sure that each image has a caption to go with it:</p>



<p><img decoding="async" width="850" height="562" class="alignnone size-full wp-image-6309" src="https://michaelsoriano.com/wp-content/uploads/2017/11/item-caption.png" alt="Caption included" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/item-caption.png 850w, https://michaelsoriano.com/wp-content/uploads/2017/11/item-caption-300x198.png 300w, https://michaelsoriano.com/wp-content/uploads/2017/11/item-caption-768x508.png 768w" sizes="(max-width: 850px) 100vw, 850px" /><br></p>



<p>This will ouput the default gallery in WordPress. Now note that each gallery will have a &#8220;.gallery&#8221; class in them. So let&#8217;s grab all of them, and create an object with it.</p>



<pre class="wp-block-code"><code lang="JavaScript" class="language-JavaScript">var galleries = {};
    $('.gallery').each(function(i,item){
        var id = $(this).attr('id');
        var imgs = Array();
        var children = $(this).find('.gallery-item');
        $.each(children,function(){
            var imgSrc = $(this).find('img').attr('src');
            var caption = $(this).find('.wp-caption-text').html();
            var imgItem = imgSrc + "::" + caption;
            imgItem = imgItem.trim()
                        .replace(/[\n\r]+/g, '')
                        .replace(/\s{2,10}/g, '')
                        .replace('undefined','');
            imgs.push(imgItem);
        })
        galleries[id] = imgs;
    });</code></pre>



<p>Now we have a &#8220;galleries&#8221; object, with the gallery id as the indexing property. This will support multiple galleries in a page, hence the index.</p>



<p>Inside each gallery object contains properties for the source and caption (separated by a &#8220;::&#8221;).</p>



<p>So we&#8217;ll have something like below:</p>



<p><br><img decoding="async" width="776" height="307" class="alignnone size-full wp-image-6317" src="https://michaelsoriano.com/wp-content/uploads/2017/11/galleries-obj.png" alt="gallery object" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/galleries-obj.png 776w, https://michaelsoriano.com/wp-content/uploads/2017/11/galleries-obj-300x119.png 300w, https://michaelsoriano.com/wp-content/uploads/2017/11/galleries-obj-768x304.png 768w" sizes="(max-width: 776px) 100vw, 776px" /><br></p>



<p>With our object in place, we can create our carousel.</p>



<p>Let&#8217;s create the HTML. The below code is simply HTML but using Handlebars syntax.</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;script id="carousel-template" type="text/x-handlebars-template">
        &lt;div class="carousel-wrap" data-gallery="{{gallery}}">
        {{#each imgObj}}
        &lt;div class="boxed-style clearfix {{hiddenOrNot @index}}" data-index="box-index-{{@index}}">
        &lt;div class="box-style col-lg-8 col-md-8 col-sm-8 col-xs-12" style="background-image:url('{{imgSrc}}')">
            &lt;div class="triangle-left-large hidden-xs">&lt;/div>
            &lt;div class="triangle-top-large visible-xs">&lt;/div>
        &lt;/div>
        &lt;div class="box-style-copy col-lg-4 col-md-4 col-sm-4 col-xs-12">{{txt}}&lt;/div>
        &lt;/div>
        {{/each}}
        &lt;a href="#" class="carousel-previous visible-xs">Previous&lt;/a>
        &lt;a href="#" class="carousel-next visible-xs">Next&lt;/a>
        &lt;div class="carousel-controls">
        {{#each imgObj}}
            &lt;a class="trig"
                data-index="box-index-{{@index}}"
                href="#">&lt;span class="fa fa-circle" aria-hidden="true">&lt;/span>&lt;/a>
        {{/each}}
        &lt;/div> &lt;/div>
&lt;/script></code></pre>



<p>As you can see above, we are wrapping everything in it&#8217;s own &#8220;carousel-wrap&#8221;, with an attribute of &#8220;data-gallery&#8221;, along with the gallery index as the value.</p>



<p>We loop through each image and assign the values to the HTML.</p>



<p>We are using Boostrap col classes, and using a &#8220;background&#8221; for the image (not img tag). This makes our image behave properly in different viewports.</p>



<p>Note that we have &#8220;Previous&#8221; and &#8220;Next&#8221; buttons &#8211; which we&#8217;re adding for now &#8211; and will explain later.<br>Also, we&#8217;re creating the controls in the bottom, which will look like below:</p>



<p><br><img decoding="async" width="759" height="499" class="alignnone size-full wp-image-6307" src="https://michaelsoriano.com/wp-content/uploads/2017/11/desktop-view.png" alt="" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/desktop-view.png 759w, https://michaelsoriano.com/wp-content/uploads/2017/11/desktop-view-300x197.png 300w" sizes="(max-width: 759px) 100vw, 759px" /><br> <br>Back in our JavaScript, let&#8217;s register a helper called &#8220;hiddenOrNot&#8221; &#8211; which simply decides if it&#8217;s not the first image &#8211; hide everything:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">Handlebars.registerHelper('hiddenOrNot', function(ind) {
         return ind === 0 ? '' : 'hidden';
    });
    var source   = $("#carousel-template").html();</code></pre>



<p>Now let&#8217;s compile our object and output to our template.</p>



<p>Remember our delimiter &#8220;::&#8221;, that&#8217;s what we&#8217;re doing in line 8 below. Also, we&#8217;re binding events to each of the controls along with assigning hidden and active classes to both itself and the large images.<br>Finally, we remove the default WordPress gallery by using jQuery&#8217;s .<strong>remove</strong>().</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">for(gallery in galleries){
        // console.log(gallery);
        var col = {};
        col.gallery = '#' + gallery;
        col.imgObj = {};
        for($i=0;$i&lt;galleries['gallery'].length;$i++){
            var imgObj = {};
            var img = galleries['gallery'][$i].split('::');
            imgObj.txt = img[1];
            imgObj.imgSrc = img[0];
            col.imgObj[$i] = imgObj;
        } //end for each img
        var template = Handlebars.compile(source);
        $('#'+gallery).before(template(col));
        $('[data-gallery="#'+gallery+'"] a.trig').each(function(index,item){
            if(index == 0){
                $(this).addClass('active');
            }
            $(this).on('click',function(){
                var imgId = $(this).attr('data-index');
                var galleryId = $(this).closest('.carousel-wrap').attr('data-gallery');
                $('[data-gallery="'+galleryId+'"]' + ' .carousel-controls a').removeClass('active');
                $(this).addClass('active');
                $('[data-gallery="'+galleryId+'"]' + ' .boxed-style[data-index]').addClass('hidden');
                $('[data-gallery="'+galleryId+'"]' + ' [data-index="'+imgId+'"]').removeClass('hidden');
                return false;
            })
        })
        $('#'+gallery).remove();
    } //end for each gallery</code></pre>



<p>Remember our Previous and Next buttons, this is only to show up in viewports for mobile devices. That is made possible by using the &#8220;visible-xs&#8221; Bootstrap class. So, it looks like below in small devices:</p>



<p><br><img decoding="async" width="481" height="530" class="alignnone size-full wp-image-6306" src="https://michaelsoriano.com/wp-content/uploads/2017/11/mobile-view.png" alt="Carousel view" srcset="https://michaelsoriano.com/wp-content/uploads/2017/11/mobile-view.png 481w, https://michaelsoriano.com/wp-content/uploads/2017/11/mobile-view-272x300.png 272w" sizes="(max-width: 481px) 100vw, 481px" /><br>Now let&#8217;s add some events to those buttons:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">$('[data-gallery]').each(function(i,item){
        var previous = $(this).children('.carousel-previous');
        var next = $(this).children('.carousel-next');
        previous.on('click',function(){
            var currentGallery = $(this).closest('.carousel-wrap').attr('data-gallery');
            var previousBox = $('[data-gallery="'+currentGallery+'"]'+' [data-index="'+getCurrentBox(currentGallery)+'"]')
                            .prev('.boxed-style');
            if(previousBox.length !== 0){
                hideBoxes(currentGallery);
                previousBox.removeClass('hidden');
                updateDots(currentGallery);
            }
            return false;
        });
        next.on('click',function(){
            var currentGallery = $(this).closest('.carousel-wrap').attr('data-gallery');
            var nextBox = $('[data-gallery="'+currentGallery+'"]'+' [data-index="'+getCurrentBox(currentGallery)+'"]')
                            .next('.boxed-style');
            if(nextBox.length !== 0){
                hideBoxes(currentGallery);
                nextBox.removeClass('hidden');
                updateDots(currentGallery);
            }
            return false;
        })
        function updateDots(currentGallery){
            $('[data-gallery="'+currentGallery+'"] a.trig').removeClass('active');
            $('[data-gallery="'+currentGallery+'"] a[data-index="'+getCurrentBox(currentGallery)+'"]')
                .addClass('active');
        }
        function hideBoxes(currentGallery){
            $('[data-gallery="'+currentGallery+'"] .boxed-style').addClass('hidden');
        }
        function getCurrentBox(gallery){
            var curBox = $('[data-gallery="'+gallery+'"]' + ' .boxed-style').not(':hidden');
            var curBoxIndex = $(curBox).attr('data-index');
            return curBoxIndex
        }
    })</code></pre>



<p>For each button, we&#8217;re doing some logic &#8211; each of them are in functions that we can reuse.<br>Finally, let&#8217;s add some CSS styles:</p>



<pre class="wp-block-code"><code lang="css" class="language-css">.boxed-style {
    clear:both;
    display: block;
    margin-bottom: 50px;
    overflow: hidden;
    position: relative;
}
.boxed-style .box-style,
.boxed-style-vertical .box-style-vertical {
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: 380px;
    background-position-x: center !important;
    background-position-y: center !important;
    background-size: cover !important;
    padding-bottom:100px;
    box-shadow: inset 0px 0px 1px 1px rgb(234, 234, 234);
}</code></pre>



<p>This is for the carousel itself:</p>



<pre class="wp-block-code"><code lang="css" class="language-css">.carousel-wrap {
    clear: both;
    display: block;
    overflow: hidden;
    margin-bottom: 45px;
    margin-top:40px;
    position: relative;
}
.carousel-previous,
.carousel-next {
    position: absolute;
    width:48px;
    height:48px;
    text-indent: -9999px;
    top:35%;
}
.carousel-next {
    background:url('images/chevron-right.png') 0px 0px no-repeat;
    right:0;
}
.carousel-previous {
    background:url('images/chevron-left.png') 0px 0px no-repeat;
}
.carousel-wrap .boxed-style {
    margin-bottom: 0;
}
.carousel-controls {
    text-align: center;
    margin:15px 0;
}
.carousel-controls a {
    font-size:13px;
    margin-right: 3px;
    color: #ccc;
}
.carousel-controls a:hover,
.carousel-controls a:focus,
.carousel-controls a.active {
    color: #0077C8;
}</code></pre>



<p>Now you might have noticed a little triangle in our caption. This is the CSS that made that possible:</p>



<pre class="wp-block-code"><code lang="css" class="language-css">.triangle-left-large {
    width: 0;
    height: 0;
    border-top: 12px solid transparent;
    border-bottom: 12px solid transparent;
    border-right: 12px solid #eaeaea;
    position: absolute;
    right: 0;
}</code></pre>



<p>Below is the finished result. In desktop and mobile view. A live example can be found <a href="https://www.parsons.com/project/sand-creek-byway/" target="_blank" rel="nofollow noopener">here</a> (scroll down to the middle of the page).</p>



<p><br><img decoding="async" width="797" height="563" class="alignnone size-full wp-image-6310" src="https://michaelsoriano.com/wp-content/uploads/2017/11/final.gif" alt="Final output"></p>



<p><br>And that&#8217;s about it! We&#8217;ve just created a carousel without a plugin. This may be a simplistic carousel &#8211; one that can be enhanced even further. Maybe add some animations, previews, swipe events etc.</p>



<p>Hope you try it out in your projects. Leave your comments below.</p>
<p>The post <a href="https://michaelsoriano.com/convert-wordpress-default-gallery-into-a-simple-carousel-without-a-plugin/">Convert WordPress default Gallery into a simple Carousel without a plugin</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/convert-wordpress-default-gallery-into-a-simple-carousel-without-a-plugin/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
		<item>
		<title>Get all posts from WordPress REST API</title>
		<link>https://michaelsoriano.com/get-all-posts-from-wordpress-rest-api/</link>
					<comments>https://michaelsoriano.com/get-all-posts-from-wordpress-rest-api/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Thu, 22 Jun 2017 16:18:40 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=6293</guid>

					<description><![CDATA[<p>As you may know, WP REST API has a limit of 100 records per call. This is what it says in the API Docs:Now this may be enough for some people, but what if you need to get ALL of them. Here are two solutions that I came up with. 1. Using PHP We&#8217;re using [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/get-all-posts-from-wordpress-rest-api/">Get all posts from WordPress REST API</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>As you may know, WP REST API has a limit of 100 records per call. This is what it says in the <a href="https://developer.wordpress.org/rest-api/using-the-rest-api/pagination/">API Docs</a>:<br><img decoding="async" class="alignnone size-full wp-image-6361" src="https://michaelsoriano.com/wp-content/uploads/2017/06/wp-cap.png" alt="cap" width="643" height="209" srcset="https://michaelsoriano.com/wp-content/uploads/2017/06/wp-cap.png 643w, https://michaelsoriano.com/wp-content/uploads/2017/06/wp-cap-300x98.png 300w" sizes="(max-width: 643px) 100vw, 643px" /><br>Now this may be enough for some people, but what if you need to get ALL of them. Here are two solutions that I came up with.</p>



<h3 class="wp-block-heading">1. Using PHP</h3>



<p>We&#8217;re using PHP&#8217;s <a href="https://www.phpied.com/simultaneuos-http-requests-in-php-with-curl/">multi cURL</a>. This means that we are doing multiple REST calls, but doing them simultaneously. Meaning, the amount of time to do the requests &#8211; is not dependent on the number of calls you make (because they&#8217;re asynchronous).<br>So let&#8217;s begin. First in your functions.php, create a function:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">function getAllRecordsFromRest(){
   //ADD ALL CODE IN HERE...
}</code></pre>



<p>Inside your new function, is where we put the rest of our code.<br>Let&#8217;s figure out how many calls we need to make:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">$totalItems = wp_count_posts()-&gt;publish;
$callsToMake = ceil($totalItems/100);</code></pre>



<p>Let&#8217;s create an empty array and stuff it with the curl options:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">$ch = array();
for($i=0;$i&lt;$callsToMake;$i++){
    $page = $i + 1;
    $ch[$i] = curl_init(get_bloginfo('url').'/wp-json/wp/v2/posts?_embed&amp;per_page=100&amp;page='.$page);
    curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch[$i], CURLOPT_SSL_VERIFYPEER,  0);
}</code></pre>



<p>As you can see above, we&#8217;re simply looping through the $<strong>callsToMake</strong> variable, to add a $page as part of our querystring. Similar to a paging system. As part of our loop, we are passing the options for curl through <em>curl_setopt</em>().</p>



<p>Now for the calls:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">$mh = curl_multi_init();
        for($i=0;$i&lt;$callsToMake;$i++){
            curl_multi_add_handle($mh, $ch[$i]);
        }
        $running = null;
        do {
            curl_multi_exec($mh, $running);
        } while ($running);
        for($i=0;$i&lt;$callsToMake;$i++){
             if (!curl_errno($ch[$i])) {
                 $info = curl_getinfo($ch[$i]);
                 //error_log(print_r($info,true));
             }
            curl_multi_remove_handle($mh, $ch[$i]);
        }
        curl_multi_close($mh);
        $responses = array(); //array
        for($x=0;$x&lt;$callsToMake;$x++){
            $responses[$x] = json_decode(curl_multi_getcontent($ch[$x]));
        }
</code></pre>



<p>First we create a handle $mh &#8211; this is what curl uses to execute and initialize the class. We loop through our $callstoMake once more to add the handles to curl_multi_add_handle().<br>We do a do while, and execute curl. Now if if there is an error in any of the calls, we will get them in curl_getinfo().</p>



<p>Finally, we get all of the contents of our calls through curl_multi_getcontent(), and we stuff it in our newly created $responses array.</p>



<p>Now our $responses will look something like:</p>



<pre class="wp-block-code"><code lang="php" class="language-php">$responses[$response[0], $response[1], $response[2]]</code></pre>



<p>So we need to loop through them to create a big array of responses (in order).</p>



<p>So we do a final loop and do an <strong>array_push</strong>().</p>



<pre class="wp-block-code"><code lang="php" class="language-php">$final = array();
for($i=0;$i&lt;count($responses);$i++){
    for($x=0;$x&lt;count($responses[$i]);$x++){
       array_push($final,$responses[$i][$x] );
     }
}
return json_encode($final);</code></pre>



<p>Then, we return our array as a JSON string by doing json_encode($final).</p>



<p>Now all we have to do is call our PHP function &#8220;<strong>getAllRecordsFromRest</strong>()&#8221; and we should have all of our posts.</p>



<h3 class="wp-block-heading">2. Using JavaScript</h3>



<p>We also have the option of using JavaScript for our multiple calls. Let&#8217;s start by getting the number of calls in our functions.php file:</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">function getNumCalls(){
    $totalItems = wp_count_posts('posts')-&gt;publish;
    $callsToMake = ceil($totalItems/100);
    return $callsToMake;
}</code></pre>



<p>Now, in our header.php &#8211; let&#8217;s create a JavaScript variable that stores the number of calls to make &#8211; from the function that we created above:</p>



<pre class="wp-block-code"><code lang="markup" class="language-markup">&lt;script&gt;
    var numOfCalls = "&lt;?php echo getNumCalls(); ?&gt;";
&lt;/script&gt;</code></pre>



<p>Now, let&#8217;s create an array, that houses all of the responses, from our AJAX calls.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript"> var requests = Array();
 for(var i=0; i&lt;numOfCalls; i++){
     var request = $.get('/wp-json/wp/v2/posts?_embed&amp;per_page=100&amp;page='+(i+1));
     requests.push(request);
 }</code></pre>



<p>We then to a &#8220;.when()&#8221; to fire our calls. And doing a console.log() on the arguments, we see the responses. This technique is described in my previous post <a href="https://michaelsoriano.com/working-with-jquerys-ajax-promises-and-deferred-objects/">Working with Promise and Deferred</a>.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">$.when.apply($,requests).done(function(){
   console.log(arguments);
})</code></pre>



<p><img decoding="async" width="450" height="350" class="alignnone size-full wp-image-6355" src="https://michaelsoriano.com/wp-content/uploads/2017/06/using-js.png" alt="Using JS" srcset="https://michaelsoriano.com/wp-content/uploads/2017/06/using-js.png 450w, https://michaelsoriano.com/wp-content/uploads/2017/06/using-js-300x233.png 300w" sizes="(max-width: 450px) 100vw, 450px" /></p>



<p>Finally, let&#8217;s do a couple of for loops to merge the contents into one big array.</p>



<pre class="wp-block-code"><code lang="javascript" class="language-javascript">$.when.apply($,requests).done(function(){
    for(var i=0; i&lt;arguments.length; i++){
       for(var x=0; x&lt;arguments[i][0].length; x++){
            final.push(arguments[i][0][x]);
        }
    }
    console.log(final); //HERE ARE OUR RECORDS
}</code></pre>



<p>And that should do it. Using either of these techniques should overcome the 100 record limitation of pulling records from WordPress REST api.<br>&nbsp;</p>
<p>The post <a href="https://michaelsoriano.com/get-all-posts-from-wordpress-rest-api/">Get all posts from WordPress REST API</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/get-all-posts-from-wordpress-rest-api/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>Show number of posts out of total records  in WordPress</title>
		<link>https://michaelsoriano.com/show-number-of-posts-out-of-total-records-in-wordpress/</link>
					<comments>https://michaelsoriano.com/show-number-of-posts-out-of-total-records-in-wordpress/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Tue, 15 Mar 2016 02:59:48 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">http://michaelsoriano.com/?p=5540</guid>

					<description><![CDATA[<p>From time to time, I just look at my blogs and see what I can add to it to make it more appealing to the user. I&#8217;ve always admired those sites that tell you what number of posts a certain category has, and what number of posts it is currently showing. So I set out [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/show-number-of-posts-out-of-total-records-in-wordpress/">Show number of posts out of total records  in WordPress</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>From time to time, I just look at my blogs and see what I can add to it to make it more appealing to the user. I&#8217;ve always admired those sites that tell you what number of posts a certain category has, and what number of posts it is currently showing. So I set out to do just that.<br />
Since I haven&#8217;t written anything WordPress related for a while, I figured this would be good practice. What we&#8217;re writing is something like below:<br />
<img decoding="async" class="alignnone size-full wp-image-5542" src="https://michaelsoriano.com/wp-content/uploads/2016/03/numposts1.png" alt="numposts1" width="651" height="389" srcset="https://michaelsoriano.com/wp-content/uploads/2016/03/numposts1.png 651w, https://michaelsoriano.com/wp-content/uploads/2016/03/numposts1-300x179.png 300w" sizes="(max-width: 651px) 100vw, 651px" /><br />
You see, we want to show what posts are currently showing &#8211; out of how many total records. It&#8217;s not a hard task &#8211; since all we really need are 2 variables: the current total showing and the total number found.</p>
<h3>The $wp_query Object</h3>
<p>According to the <a href="https://codex.wordpress.org/Class_Reference/WP_Query">codex</a>, the WP_Query class &#8220;deals with the intricacies of a post&#8217;s (or page&#8217;s) request to a WordPress blog&#8221;. This means that WordPress has already done the heavy lifting when it comes to information needed when you query your posts. Information needed when building stuff like paging, queries, templates and meta data.<br />
In our case, we need the meta data &#8211; of the posts returned. So first off, open the index.php file in your theme directory and just outside the loop, add the code below:</p>
<pre>print_r($wp_query);exit;
</pre>
<p>What we&#8217;re doing is seeing what the <strong>$wp_query</strong> is holding. $wp_query is the object that is derived from the WP_Query class that we talked about above. You will see a long array of information that pertains to the current request. So say you&#8217;re in a certain category, this object will contain information about that category and the posts that it contains.<br />
So somewhere in this object lies the information we need. Let&#8217;s grab &#8220;post_count&#8221; and &#8220;found_posts&#8221;.<br />
<img decoding="async" class="alignnone size-full wp-image-5545" src="https://michaelsoriano.com/wp-content/uploads/2016/03/numposts2.png" alt="numposts2" width="466" height="592" srcset="https://michaelsoriano.com/wp-content/uploads/2016/03/numposts2.png 466w, https://michaelsoriano.com/wp-content/uploads/2016/03/numposts2-236x300.png 236w" sizes="(max-width: 466px) 100vw, 466px" /><br />
Now that we know the property names, we can go ahead and remove the print_r that we have.</p>
<h3>The Output</h3>
<p>This is as simple as it gets. All we need is to check if &#8220;post_count&#8221; is more than 0 and we can echo out our sentence. We can hard code the &#8220;1&#8221; since we&#8217;re always going to be showing at least 1 record.</p>
<pre><!--?php if($wp_query-&gt;post_count &gt; 0): ?-->
    Showing 1 through <!--?php echo $wp_query-&gt;post_count ?--> out of <!--?php echo $wp_query-&gt;found_posts; ?--> articles..
<!--?php endif; ?-->
</pre>
<p>The code above should work anywhere in your theme. It&#8217;s especially useful in your archive templates &#8211; so users can tell how many articles are in a specific category etc. It&#8217;s a good addition to your paging in the footer as well.<br />
To test it, try searching for something, or click on a category. The &#8220;found_posts&#8221; should depend on the current request, while the &#8220;post_count&#8221; depends on the limit that you have in your WordPress settings.<br />
And that&#8217;s it. Hopefully you can find this snippet useful in your theme somewhere. Please leave your comments below.</p>
<p>The post <a href="https://michaelsoriano.com/show-number-of-posts-out-of-total-records-in-wordpress/">Show number of posts out of total records  in WordPress</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/show-number-of-posts-out-of-total-records-in-wordpress/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Add an additional Body Class to WordPress by using the Post Slug</title>
		<link>https://michaelsoriano.com/add-an-additional-body-class-to-wordpress-by-using-the-post-slug/</link>
					<comments>https://michaelsoriano.com/add-an-additional-body-class-to-wordpress-by-using-the-post-slug/#comments</comments>
		
		<dc:creator><![CDATA[Michael Soriano]]></dc:creator>
		<pubDate>Mon, 11 May 2015 02:40:50 +0000</pubDate>
				<category><![CDATA[WordPress]]></category>
		<guid isPermaLink="false">http://fearlessflyer.com/?p=4405</guid>

					<description><![CDATA[<p>One of the real useful things I&#8217;ve come across with WordPress is the body_class() method. This adds several classes to the body element of your HTML. The output looks something like below: Why is this so great? Now you can style your pages very efficiently because you&#8217;re able to select from the template you&#8217;re using, [&#8230;]</p>
<p>The post <a href="https://michaelsoriano.com/add-an-additional-body-class-to-wordpress-by-using-the-post-slug/">Add an additional Body Class to WordPress by using the Post Slug</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>One of the real useful things I&#8217;ve come across with WordPress is the <a href="https://codex.wordpress.org/Function_Reference/body_class">body_class</a>() method. This adds several classes to the body element of your HTML. The output looks something like below:<br />
<img decoding="async" class="alignnone size-full noborder wp-image-4406" src="https://michaelsoriano.com/wp-content/uploads/2015/05/body-class.jpg" alt="body-class" width="694" height="193" /><br />
Why is this so great? Now you can style your pages very efficiently because you&#8217;re able to select from the template you&#8217;re using, the post type, when user is logged in &#8211; even to the post Id.<br />
An example of what I mean is say &#8211; you want all the H1 tags styled differently only for post ID &#8220;4396&#8221;. Now in you CSS file you can add a rule like below:</p>
<pre>.postid-4396 h1 {
   text-decoration: underline;
   font-size: 45px;
}
</pre>
<p>This will effectively target only that post&#8217;s h1 tags. Pretty useful right?</p>
<h3>Add a Post slug to the Body Class</h3>
<p>Now let&#8217;s take it a step further. If you&#8217;re like me who develop themes all day &#8211; you probably have a local server set up. Now, the problem with that is &#8211; you may not have your WordPress databases the same as the production site. So your post ids may not be the same!<br />
The solution: use the post slug as an additional class. For example, you want to style the &#8220;About us&#8221; page&#8217;s H1 tags differently than the rest of the pages. So instead of relying on the default body_class()&#8217;s post id, simply add the code below to your functions.php file:</p>
<pre>function getPostSlug(){
    global $post;
    $slug = '';
    if(is_object($post)){
       $slug = $post-&gt;post_name;
    }
    return $slug;
}
</pre>
<p>Then, in your header.php file (or where you have your opening body tag is), add the call to the body_class():</p>
<pre>&gt;
</pre>
<p>The output will be something like below:<br />
<img decoding="async" class="alignnone size-full noborder wp-image-4407" src="https://michaelsoriano.com/wp-content/uploads/2015/05/body-class-2.jpg" alt="body-class-2" width="694" height="193" /><br />
Now you can code your CSS like so:</p>
<pre>.about-us h1 {
   text-decoration: underline;
   font-size: 45px;
}
</pre>
<h3>Conclusion</h3>
<p>Pretty neat right? Adding a body class that is based on your post slug is not only very helpful, but also very semantic. The upside of using the slug is its always lowercase and no spaces (unless you change them when you create a post). But then &#8211; you can deal with that accordingly. Tell me your comments below.</p>
<p>The post <a href="https://michaelsoriano.com/add-an-additional-body-class-to-wordpress-by-using-the-post-slug/">Add an additional Body Class to WordPress by using the Post Slug</a> appeared first on <a href="https://michaelsoriano.com">Michael Soriano</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://michaelsoriano.com/add-an-additional-body-class-to-wordpress-by-using-the-post-slug/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
