Rewriting A Static Website Using Gatsby and GraphQL - Part 2
Tags: gatsby, graphql, jsx, javascript
Published: 2019-03-04 16:02:57

---
title: Rewriting A Static Website Using Gatsby and GraphQL - Part 2
published: true
description: I decided to update my personal site away from Jekyll. In the process I learned about GatsbyJS, GraphQL and all of the errors! Check out this series for a granular walkthrough. In this post I tackle the syntax to replace Liquid templating in my html files.
tags: gatsbyjs, graphql, JSX, javascript
canonical_url: https://tenmilesquare.com/rewriting-a-static-website-using-gatsby-and-graphql-part-2/
series: Rewriting A Static Website Using Gatsby and GraphQL
---


<b>Originally posted on <a rel="noreferrer noopener" aria-label="ten mile square site (opens in a new tab)" href="https://tenmilesquare.com/blog/" target="_blank">Ten Mile Square's blog.</a></b>


<!-- wp:paragraph -->
<p>This is part 2 of a 3 part series about the decision to rewrite my <a href="https://laurieontech.com" target="_blank" rel="noreferrer noopener" aria-label="personal site (opens in a new tab)">personal site</a> using <a href="https://www.gatsbyjs.org/">GatsbyJS</a> and <a href="https://graphql.org/">GraphQL</a>. In my last post, I discussed how to query against static Yaml files in order to display my data; things like speaking engagements, blog posts, etc. In the process I went over concepts like GraphQL queries, GatsbyJS plugins and JSX considerations (and errors, lots of errors). Go read that <a href="https://tenmilesquare.com/rewriting-a-static-website-using-gatsby-and-graphql/">post</a> first if you want to follow along in order. </p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Removing Liquid Templating </h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Now that I have the data from my Jekyll site copied over and playing nicely with Gatsby, I have to address some of the incompatible markup I was previously using in my html. In my Jekyll site, I was using <a href="https://shopify.github.io/liquid/">Liquid</a> to embed some simple logic into my pages; things like if/else statements, loops, etc. </p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Loops</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>So to start, I'm going to replace all the loops I was using, like this one.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<pre class="wp-block-code code">{% raw %}{% for speaking in site.data.speaking reversed %}
        &lt;div class="conference"&gt;
             &lt;p class="date"&gt;{{ speaking.date }}&lt;/p&gt;
        &lt;/div&gt;
{% endfor %}{% endraw %}
</pre>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>I can do this by replacing the loops with JSX map functions, so it looks like this.  </p>
<!-- /wp:paragraph -->

```jsx
{data.allSpeakingYaml.edges.map(({ node }) => (
       <div key={node.date} className="conference"> 
          <p className="date"> {node.date} </p>
       </div>
))}
```

<!-- wp:paragraph -->
<p>Note that the previous loop went through the list in reverse. I'll worry about that piece later, this works for now.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>If Statements</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>So now that I've replaced all my loops I'm going to turn my attention to the if statements. Most of the if/else statements I'm using are for styles and display. Unfortunately, since Liquid does not work in JSX, I need alternative ways of triggering these cases. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So in this first case I'm assigning a style depending on whether or not an element is the first element in a list. </p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<pre class="wp-block-code code">{% raw %}&lt;li class="wrapper 
{% if forloop.first %} style2 {% "else" %} style1 {% endif %}
"&gt;{% endraw %}
</pre>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Lucky for me this is relatively straightforward. That's because I can determine whether or not the element is the first item by its index. So I can embed a ternary operator in the class assignment and check if the index is zero or not.</p>
<!-- /wp:paragraph -->


```jsx
<li className = {index === 0 ? 'wrapper style2' : 'wrapper style1'}>
```

<!-- wp:paragraph -->
<p>Wonderful. Ternary operators are incredibly helpful. My next case is slightly more complicated because I'm not controlling the class but the existence of the element itself. Not only that, but I'm not checking for the existence of the element but the existence of an attribute of the element.</p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<pre class="wp-block-code code">{% raw %}{% if talk.video %}
    ( &lt;a target="_blank" href="{{ talk.video }}"&gt;Video&lt;/a&gt; ) 
{% endif %}{% endraw %}
</pre>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>One of the benefits of the code we wrote in that <a href="https://tenmilesquare.com/rewriting-a-static-website-using-gatsby-and-graphql/" target="_blank" rel="noreferrer noopener" aria-label="last blog (opens in a new tab)">last blog</a> is that the second consideration is no longer relevant. In the previous post we determined that we now reference <span class="code" style="background-color:white">title</span> and <span class="code" style="background-color:white">video</span> as top level objects inside the loop, instead of <span class="code" style="background-color:white">talk.title</span> or <span class="code" style="background-color:white">talk.video</span>. Yet again, the answer is a ternary operator.</p>
<!-- /wp:paragraph -->

```jsx
<a className={video ? "" : "emptyvideo"}target="_blank" href={video}>
      Video 
</a>
```

<!-- wp:paragraph -->
<p>The above code determines the existence of <span class="code" style="background-color:white">video</span> and assigns a class to the div. All that's left is to disappear the content inside the div with that class, like this.</p>
<!-- /wp:paragraph -->

```css
.emptyvideo {
     display: none;
}
```

<!-- wp:heading {"level":3} -->
<h3>Directional Loops</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The final Liquid reference I need to remove is actually related to something we've already seen. Remember the <span class="code" style="background-color:white">`reversed`</span> notation I was using in my loops above? </p>
<!-- /wp:paragraph -->

<!-- wp:html -->
<pre class="wp-block-code code">{% raw %}{% for speaking in site.data.speaking <strong>reversed</strong> %}
     &lt;div class="conference"&gt;
         &lt;p class="date"&gt;{{ speaking.date }}&lt;/p&gt;
     &lt;/div&gt;
{% endfor %}{% endraw %}
</pre>
<!-- /wp:html -->

<!-- wp:paragraph -->
<p>Now it's time to handle that functionality. Previously, I was looping through my Yaml file in the order that I'd listed the data within that file. That meant I could add new talks or blog posts to the bottom of my Yaml file and it would display that content first. I still want to do that so I don't accidentally mess up the file by adding new stuff to the top of it. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Unfortunately, I can't reverse the map function we're now using in JSX. I need to figure out another way. As it turns out, going back to my GraphQL query is the answer. However, you can’t sort in GraphQL against the implicit ordering of your resource, in this case the order that I listed my data in the Yaml file. So, I need something within that data to sort on. Lucky for me my speaking data has dates included in the attributes. </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>So using "reverse" chronology just means updating my query to pull in the data using those dates, with the most recent one first.</p>
<!-- /wp:paragraph -->

```graphql
{
    allSpeakingYaml (sort: {fields: [date], order: DESC}) {
        edges {
            node {
                conference
                year
                url
                talks {
                    title 
                    video
                }
            }
        }
    }
}
```

<!-- wp:paragraph -->
<p>Now my map is displaying the data in reverse chronological order because the data is given to it in that order. Even though I had a date field to use in this case that isn't strictly necessary. I could have just as easily added an id or index or whatever else would give me ordering. And note that it isn't necessary for the field GraphQL is using to sort to be one of the attributes queried for return.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>After all of this I finally have fully functionally pages
written with JSX and accessing my Yaml data. However, I’m not currently taking
advantage of one of the best parts of Gatsby, image processing. I’ll tackle
that in the next post.</p>
<!-- /wp:paragraph -->