<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jack Harner 🚀</title>
    <description>The latest articles on Forem by Jack Harner 🚀 (@jackharner).</description>
    <link>https://forem.com/jackharner</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F81934%2F93fc429c-5ea6-4a2f-979c-b5835b861d13.jpg</url>
      <title>Forem: Jack Harner 🚀</title>
      <link>https://forem.com/jackharner</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jackharner"/>
    <language>en</language>
    <item>
      <title>Starting A Freelance Developer Bluesky Feed</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Wed, 26 Mar 2025 00:00:00 +0000</pubDate>
      <link>https://forem.com/jackharner/starting-a-freelance-developer-bluesky-feed-kac</link>
      <guid>https://forem.com/jackharner/starting-a-freelance-developer-bluesky-feed-kac</guid>
      <description>&lt;p&gt;For my first dip into the &lt;a href="https://atproto.com" rel="noopener noreferrer"&gt;AT Protocol&lt;/a&gt;, I decided I would try my hand at setting up a Feed. If you're unaware the AT Protocol is a decentralized framework for social media. In short, instead of the Tech Giants up on their flying mansions deciding what your social media feed should be, the ATProto gives that power back to the people.&lt;/p&gt;

&lt;p&gt;There are a ton of great feeds popping up, but my goal is to make one specific to Freelance Developers. I've got the &lt;a href="https://bsky.app/profile/renrah.dev/feed/freelanceDevs" rel="noopener noreferrer"&gt;feed up and running here&lt;/a&gt; if you want to check it out or shoot me a &lt;a href="https://bsky.app/profile/jackharner.com" rel="noopener noreferrer"&gt;DM on Bluesky (@JackHarner.com)&lt;/a&gt; if you want to get added to it!&lt;/p&gt;

&lt;p&gt;Let's get into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;This isn't really a tutorial of how to set up a Bluesky feed (although I might have some stuff for that in the works) but you basically get started with their &lt;a href="https://github.com/bluesky-social/feed-generator" rel="noopener noreferrer"&gt;Feed Generator template&lt;/a&gt;. It's a TypeScript based Node/Express application that handles the ingesting of the greater ATProto network (the firehose), storing posts you deem appropriate, and then outputting a "Feed Skeleton" (list of post URIs) that Bluesky (or whatever AppView) then populates with the post data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Determining If A Post is Related to the Feed Topic
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep in mind, I don't rally know anything about writing algorithms. I know how to build website and program and a ton of other stuff but this is all new to me. If you have suggestions or constructive critisicm, hit me up &lt;a href="https://bsky.app/profile/jackharner.com" rel="noopener noreferrer"&gt;@JackHarner.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A lot of the feeds you see popping up are really just keyword scrapers: "If a post has X Y or Z in it, display it". Some even tell you: "Include #StarSky to have your post included". For as specific as a niche as "Freelance Developers" is, a basic keyword filter isn't going to cut it.&lt;/p&gt;

&lt;p&gt;I decided to set up a score-based system to try to determine if a post is related to freelance development specifically. Let's walk through the evolution of that score system (it's still a work in progress).&lt;/p&gt;

&lt;p&gt;I started with a list of a bunch of freelance related and development related terms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const terms = [
    'freelance dev',
    'freelance devs',
    'freelance developer',
    'html',
    'js',
    // etc...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I went through and assigned point values to each term based on how likely I thought a post would make sense to be included in the feed based on having that term in there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const terms = [
    {term: 'freelance dev', points: 20},
    {term: 'freelance devs', points: 20},
    {term: 'freelance developer', points: 20},
    {term: 'html', points: 5},
    {term: 'js', points: 5},
    // etc...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I would then take each post coming down the firehose and score them based on how many terms (and their point values) it could find in the post text. I had a score threshold defined and if the post had a higher score than that, it got stored in the database and output in the feed.&lt;/p&gt;

&lt;p&gt;That worked for a little while but I noticed that some spammy type posts I didn't like were ending up in there. I don't know if you caught the bug for this already but if you had a post that said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I'm a freelance developer"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It would match for both &lt;code&gt;freelance developer&lt;/code&gt; AND &lt;code&gt;freelance dev&lt;/code&gt; giving that post a whopping 40 points.&lt;/p&gt;

&lt;p&gt;If you posted some spam like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Best Freelancers in LA / Best Freelance Writers in OC / Best Freelance Freelancer Editors Freelances Free Devs."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You would get a shit load of points when you shouldn't have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refining the Algorithm
&lt;/h2&gt;

&lt;p&gt;In order to find and present the most relevant Freelance Developer content on the network, I had to do better than that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Negative Points
&lt;/h3&gt;

&lt;p&gt;I included the ability to add negative point terms so I can set "freelance editor" or "freelance writer" to -30 points so it doesn't necesarily get blocked if that term exists, but there needs to be more content about development to make up for the negative score.&lt;/p&gt;

&lt;h3&gt;
  
  
  No More Stacking Points
&lt;/h3&gt;

&lt;p&gt;I updated the Allow List terms to let the term be defined as an array of similar terms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const terms = [
    {term: ['freelance dev', 'freelance devs', 'freelance developer'], points: 20},
    {term: 'html', points: 5},
    {term: ['javascript', 'js', 'jsx'] points: 5},
    // etc...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way if it finds both "freelance devs" and "freelance developer" in the same post, it only gets 20 points, regardless of how many times it appears in the post.&lt;/p&gt;

&lt;p&gt;I also updated the scoring to look for those terms specifically, either at the start of the text with a space after it, a space on both sides, or at the end of the string. Thanks to ChatGPT for the REGEX because that shit is UGLLYY:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for (const t of termsToCheck) {
    const termRegex = new RegExp(\\b${t.toLowerCase().replace(/[.*+?^${}()|[\\]\\\\]/g, '\\$&amp;amp;')}\\b)
    if (termRegex.test(lowerPost)) {
    found = true
    break
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents false positives by preventing "dev" from triggering for "devout", for example.&lt;/p&gt;

&lt;h3&gt;
  
  
  AllowList and BlockList Authors
&lt;/h3&gt;

&lt;p&gt;I also want to be able to display posts from people I know are freelance / indie developers without a post having to explicitly be about freelance development. I created an Allowlist and a Blocklist of author DIDs (&lt;a href="https://en.wikipedia.org/wiki/Decentralized_identifier" rel="noopener noreferrer"&gt;Decentralized Identifiers&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;If I put a DID in the Allowlist, their post score threshold gets chopped in half. I might even need to lower that because I've added some Devs and haven't really seen any extra posts get added.&lt;/p&gt;

&lt;p&gt;There were a couple people who were pretty routinely showing up in the feed during my initial testing even though they weren't talking about freelance development, or they just posted some spammy stuff. Their DID's got added to the Blocklist. If I add a DID to the Blocklist, it just doesn't even try to score their post when one comes out of the firehose.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;I'm going to continue to try to refine my point system as well as tracking down other Freelance / Indie Developers to add to the list. If that's you, &lt;a href="https://bsky.app/profile/jackharner.com" rel="noopener noreferrer"&gt;shoot me a DM on Bluesky&lt;/a&gt; and I'll add you!&lt;/p&gt;

&lt;p&gt;Give the feed a like, pin, or share if you feel so inclined! &lt;a href="https://bsky.app/profile/renrah.dev/feed/freelanceDevs" rel="noopener noreferrer"&gt;Freelance Devs Bluesky Feed&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Custom Menu Order in the WordPress Admin</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Wed, 20 Jul 2022 00:00:00 +0000</pubDate>
      <link>https://forem.com/jackharner/custom-menu-order-in-the-wordpress-admin-l36</link>
      <guid>https://forem.com/jackharner/custom-menu-order-in-the-wordpress-admin-l36</guid>
      <description>&lt;h2&gt;
  
  
  Turn On The Custom Admin Menu Hook
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;custom_menu_order&lt;/code&gt; hook is a simple hook that just tells WordPress you want to display the Admin menu in a custom order. You filter it with &lt;code&gt;add_filter()&lt;/code&gt; and can just use the built-in function &lt;code&gt;__return_true&lt;/code&gt; to (you can probably guess) return true to the hook.&lt;/p&gt;

&lt;p&gt;Add this to your &lt;code&gt;functions.php&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; add_filter( 'custom_menu_order', '__return_true' );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;a href="https://developer.wordpress.org/reference/hooks/custom_menu_order/"&gt;Docs&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ORDER IN THE... WordPress Admin!
&lt;/h2&gt;

&lt;p&gt;Now that Custom Menu Order is turned on, it's time to actually set the order. This is controlled through the &lt;code&gt;menu_order&lt;/code&gt; hook.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add_filter( 'menu_order', '&amp;lt;custom_menu_order_fn_name&amp;gt;', 10, 1 );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hook sends an array of the current menu item's URLs as the only parameter. Keep in mind it is only the part of the url AFTER &lt;code&gt;/wp-admin/&lt;/code&gt;, but including all of the url parameters:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For example the Pages menu links to &lt;code&gt;https://example.wp/wp-admin/edit.php?post_type=page&lt;/code&gt; and you just turn it into: &lt;code&gt;edit.php?post_type=page&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can either add and remove things individually from the Menu, or return a completely new array with only the items you want in the order you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Removing Posts Menu (All Posts, Add New, etc.) from WP Admin
&lt;/h3&gt;

&lt;p&gt;Using the PHP function &lt;code&gt;array_search()&lt;/code&gt; returns the array index for a specific value. If you wanted to remove a specific menu/submenu completely, you just search for the top level pages URL, and use PHP's &lt;code&gt;unset()&lt;/code&gt; to remove the item from the array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function jh_remove_posts_menu( $menu_ord ) {
    if (($key = array_search('edit.php', $menu_ord)) !== false) {
        unset($menu_ord[$key]);
    }
    return $menu_ord;
}
add_filter( 'menu_order', 'jh_remove_posts_menu', 10, 1 );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Totally Custom WP Admin Menu Order
&lt;/h3&gt;

&lt;p&gt;Here's an example of throwing out the default menu order and returning an entirely new one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is probably the way to go if you're going to be moving or removing more than one item from the menu. It's easier to just set the order explicitly, instead of fighting with the array the hook provides.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function jh_custom_menu_order( $menu_ord ) {

    return array(
        'index.php', // Dashboard
        'separtor1', // First separator
        'edit.php', // Posts
        'edit.php?post_type=page', // Pages
        'edit.php?post_type=&amp;lt;custom post type&amp;gt;', // Custom Post Type 
        'separator2', // Second separator
        'upload.php', // Media
        'edit-comments.php', // Comments
        'separator3', // Third separator
        'users.php', // Users
        'themes.php', // Appearance
        'plugins.php', // Plugins
        'tools.php', // Tools
        'options-general.php', // Settings
        'separator-last', // Last separator
    );
 }
 add_filter( 'menu_order', 'jh_custom_menu_order', 10, 1 );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The order of the items in the array determines the order of the menu. You can add and leave out any pages that are accessible from the WordPress Admin.&lt;/p&gt;

&lt;p&gt;Don't worry though, the menu still respects User Role Capabilities, so if you add the Settings menu, it still only shows up for the Administrator role.&lt;/p&gt;

&lt;h2&gt;
  
  
  Order Array of Core WordPress Pages
&lt;/h2&gt;

&lt;p&gt;As of WordPress v6.0.1, this is the default menu order that gets passed to your &lt;code&gt;menu_order&lt;/code&gt; filter function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; [
    'index.php',
    'separator1',
    'edit.php',
    'upload.php',
    'edit.php?post_type=page',
    'edit-comments.php',
    'separator2',
    'themes.php',
    'plugins.php',
    'users.php',
    'tools.php',
    'options-general.php',
    'separator-last',
 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>wordpress</category>
    </item>
    <item>
      <title>Reset WordPress File Permissions</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Mon, 19 Jul 2021 00:00:00 +0000</pubDate>
      <link>https://forem.com/jackharner/reset-wordpress-file-permissions-2h2i</link>
      <guid>https://forem.com/jackharner/reset-wordpress-file-permissions-2h2i</guid>
      <description>&lt;p&gt;&lt;a href="https://jackharner.com/blog/reset-wordpress-file-permissions/"&gt;Originally Posted to JackHarner.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Somehow I continuously run into File Permissions Issues while working with WordPress, so this is primarily just a reference for myself. For whatever reason, things can get pretty hectic, and you've probably ran into a similar issue if you've ever seen a "Permission Denied" error, or if WordPress asks you for your FTP Connection Information to update a plugin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q-kRRxj8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jackharner.com/static/bed1aeac20e55f178ab525719878f31c/5c6e9/connection.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q-kRRxj8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jackharner.com/static/bed1aeac20e55f178ab525719878f31c/5c6e9/connection.png" alt="WordPress asking for Connection Information" title="WordPress asking for Connection Information"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sometimes it's just best to reset everything back to the way Apache needs it to be to run smoothly: &lt;code&gt;775&lt;/code&gt; on folders, and &lt;code&gt;664&lt;/code&gt; on files.&lt;/p&gt;

&lt;p&gt;Run the following 3 terminal commands from the root of your WordPress install (the folder containing your &lt;code&gt;wp-config.php&lt;/code&gt; file):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chown www-data:www-data -R * # Set Apache's www-data user as the owner
find . -type d -exec chmod 775 {} \; # Change folder permissions to rwxrwxr-x
find . -type f -exec chmod 664 {} \; # Change file permissions to rw-rw--r--
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm sure future me is thanking "now" me for writing this down so I can stop googling it. You're welcome future me!&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Best Options For Recurring Developer Income?</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Sun, 25 Apr 2021 02:01:18 +0000</pubDate>
      <link>https://forem.com/jackharner/best-options-for-recurring-developer-income-4m46</link>
      <guid>https://forem.com/jackharner/best-options-for-recurring-developer-income-4m46</guid>
      <description>&lt;p&gt;As a Freelance developer, what's the best way to get recurring income? &lt;/p&gt;

&lt;p&gt;Things like maintenance plans, monthly hosting packages, etc. I'd love to hear what's worked and what didn't for you!&lt;/p&gt;

</description>
      <category>career</category>
      <category>freelance</category>
      <category>money</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Destructuring and Nested Destructuring in ES6</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Sun, 18 Oct 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/jackharner/destructuring-and-nested-destructuring-in-es6-k2c</link>
      <guid>https://forem.com/jackharner/destructuring-and-nested-destructuring-in-es6-k2c</guid>
      <description>&lt;p&gt;Have you ever had a JavaScript object that you needed to extract a bunch of different values out of? Today I'd like to introduce you to your new best friend: ES6 Destructuring.&lt;/p&gt;

&lt;p&gt;ES6 brings with it a bunch of nifty new ways to do things with JavaScript. One of the things I use ALL THE TIME is Destructuring. It allows you to pick and choose properties out of an object and automatically assign them to a variable.&lt;/p&gt;

&lt;p&gt;Take the following JavaScript Object for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Previously, if you needed to use and manipulate the different properties of that object you would have to assign each variable manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;married&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;married&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;married&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's do that again with ES6. You'll find it's a whole lot cleaner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;married&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 26&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Not Just Objects Either!
&lt;/h2&gt;

&lt;p&gt;Destructuring is not just for Objects, you can even use it on an Array!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jovi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;second&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;third&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Bon"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It assigns the items in your array, in order, to the corresponding variable in the destructuring array.&lt;/p&gt;

&lt;p&gt;If, for whatever reason, you need to skip the first two items in the array you can do so with just a comma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Jovi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[,&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;only&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;people&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;only&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Jovi"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Nested Destructuring
&lt;/h2&gt;

&lt;p&gt;In the real world, you're probably going to have more complex objects than just that, so let's take a look at a more complex object example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Robert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;spouse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Roberta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;anniversary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;01-01-1970&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;kids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given this more in depth Object, how would you go about getting &lt;em&gt;just&lt;/em&gt; Robert's spouse's name? Any Ideas? With a little magical thing called "Nested Destructuring".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;spouse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Roberta"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Nested Destructuring, you can cherry pick properties to get from as many levels down in your object as you need. Obviously this can get pretty messy pretty quickly so feel free to destructure more than once in order to keep your code clean.&lt;/p&gt;

&lt;p&gt;Keep in mind, when you destructure down into a property, like the example above, it does not set the variable of the property you went down in to. So in this case both &lt;code&gt;spouse&lt;/code&gt; and &lt;code&gt;married&lt;/code&gt; are undefined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;spouse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spouse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need &lt;code&gt;spouse&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; as separate variables you will have to destructure more than once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;spouse&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;spouse&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;spouse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// {name: "Roberta", age: 62}&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Roberta"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What If I Need To Destructure To A Different Variable Name?
&lt;/h2&gt;

&lt;p&gt;Sometimes in the real world, data comes in with weird property names, or you need to extract different nested properties that happen to have the same name. Don't worry though, ES6 has you covered.&lt;/p&gt;

&lt;p&gt;Let's keep using our more complex person Object and extract BOTH his and his wife's name at the same time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Robert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;spouse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Roberta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;anniversary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;01-01-1970&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;kids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Based on what we've gone over so far, your first thought might be to do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;spouse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However if you were to try this you'd be met with a nice fat "Duplicate Assignment" error because you're trying to set the &lt;code&gt;name&lt;/code&gt; variable twice. Babel or whatever ES6 Compiler you're using won't like that at all, so you need to define custom variable names.&lt;/p&gt;

&lt;p&gt;Check it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hisName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;married&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;spouse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;herName&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hisName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; Is Married To &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;herName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="c1"&gt;// Robert Is Married To Roberta&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All you're doing is saying "Take this property and extract as this specific variable". Which when compiled to regular JavaScript for your browser it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;hisName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;herName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;married&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Keep It Clean, and Keep It Simple
&lt;/h2&gt;

&lt;p&gt;Using Destructuring allows you to cleanly and simply extract properties from objects in ES6 JavaScript into variables to be manipulated and modified. Keep It Simple Stupid and hit me up on Twitter &lt;a href="https://twitter.com/jackharner"&gt;@JackHarner&lt;/a&gt; if you learned something!&lt;/p&gt;




&lt;h3&gt;
  
  
  Featured Image by &lt;a href="https://unsplash.com/@ripato?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Ricardo Gomez Angel&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/structure?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;
&lt;/h3&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
    </item>
    <item>
      <title>Productivity = Automation</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Wed, 01 Jul 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/jackharner/productivity-automation-31mi</link>
      <guid>https://forem.com/jackharner/productivity-automation-31mi</guid>
      <description>&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media ltag__twitter-tweet__media__video-wrapper"&gt;
        &lt;div class="ltag__twitter-tweet__media--video-preview"&gt;
          &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TVLXaoZl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/tweet_video_thumb/EbzV6uMWkAYqqU5.jpg" alt="unknown tweet media content"&gt;
          &lt;img src="/assets/play-butt.svg" class="ltag__twitter-tweet__play-butt" alt="Play butt"&gt;
        &lt;/div&gt;
        &lt;div class="ltag__twitter-tweet__video"&gt;
          
            
          
        &lt;/div&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--VVg_4RpN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1253165670935773185/SkSoEQL3_normal.jpg" alt="DEV Community 👩‍💻👨‍💻 profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        DEV Community 👩‍💻👨‍💻
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/thepracticaldev"&gt;@thepracticaldev&lt;/a&gt;

      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Time for &lt;a href="https://twitter.com/hashtag/DevDiscuss"&gt;#DevDiscuss&lt;/a&gt;&lt;br&gt;&lt;br&gt;Tonight's topic is... Productivity tools 🛠&lt;br&gt;&lt;br&gt;Let's start with some questions&lt;br&gt;&lt;br&gt;- What does it mean to be productive?&lt;br&gt;- How does your view on tools evolve over time?&lt;br&gt;- Recommend some tools! 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      01:01 AM - 01 Jul 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1278131605878562818" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1278131605878562818" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1278131605878562818" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  I'm Lazy.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;BUT&lt;/strong&gt; I'm the good kind of lazy that works really hard to do as little actual work as possible. If I have to do anything more than twice, I'm going to think about automating it. From scripts to download &amp;amp; process product photos, to hours-saving spreadsheet combiners, there's not much in my job and life that isn't at least partially fueled by automation.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Automation Toolkit
&lt;/h2&gt;

&lt;p&gt;Smarter minds than me can probably go into the depths of Pros and Cons between all of these methods, but I'm not going to. This is just a list of some of the things I've used over the years to speed up mundane tasks. Everything here was used to solve a super specific problem, so think about things in your work day that can be sped up with the help of our friendly &lt;del&gt;overlords&lt;/del&gt; computers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  If It's Repetitive, You Can Probably Get a Computer to Do It For You.
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;Python is often reached for when starting to learn programming. It's simple, it's easy to read, and you don't get lost in a sea of brackets and semi-colons. At the same time it's insanely powerful and I'm sure a very large chunk of the online world is run with python.&lt;/p&gt;

&lt;p&gt;Need to process or combine large spreadsheets on a recurring basis? Check out Pandas.&lt;/p&gt;

&lt;p&gt;Want to automate certain mundane tasks online? Check out Selenium (more on that later 👇).&lt;/p&gt;

&lt;p&gt;Want to make Generative Art or play with fractals? &lt;a href="https://simpleprogrammer.com/python-generative-art-math/"&gt;Python can do that too&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Selenium
&lt;/h3&gt;

&lt;p&gt;Need to submit the same form on a webpage over and over again? Time to bust out Selenium. Selenium is a tool you can use with Python (or Java) to write code to make a browser do things to itself 😉. Python is super verbose and easy to read so you're just telling the browser:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Go Here, type XYZ into that Form, click on this checkbox and then click on that submit button"&lt;/p&gt;
&lt;h3&gt;
  
  
  "Now do it 999 more times"
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;With Great Scripting Power Comes Great Responsibility&lt;/strong&gt;. Don't accidentally (or &lt;strong&gt;intentionally&lt;/strong&gt; ) DoS anybody by bombarding their site with requests. Build in exits and control the timing of requests. All That Fun Stuff.&lt;/p&gt;

&lt;h3&gt;
  
  
  PowerShell / Bash Scripts
&lt;/h3&gt;

&lt;p&gt;PowerShell was my first introduction to scripting. I started with simple "move files around" type scripts and built more stuff from there as the need came up. I wrote a PowerShell script that could fetch product images by SKU from specific sources, crop/resize and rename the files, then upload them over FTP to our web server. What used to be a manual hour long process is now 5-10 minutes tops.&lt;/p&gt;

&lt;p&gt;Bash Scripts are basically the Linux version of PowerShell (or the other way around, I don't know). Super useful for processing things server side. Mixed with Cron, you can automate reports and file fetching fairly simply, back up and maintain your servers automatically, and more. Definitely spend some time learning Bash scripting if you do anything on Linux Servers.&lt;/p&gt;

&lt;h3&gt;
  
  
  AutoHotkey
&lt;/h3&gt;

&lt;p&gt;If your on Windows I highly recommend &lt;a href="https://www.autohotkey.com/"&gt;AutoHotkey&lt;/a&gt;. It allows you to configure almost anything as a keyboard shortcut.&lt;/p&gt;

&lt;p&gt;Some of my most used shortcuts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;]j&lt;/code&gt; will output &lt;code&gt;- Jack &amp;lt;mm/dd/yyyy&amp;gt;&lt;/code&gt; with the current date. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Ctrl + Pause&lt;/code&gt; starts and stops Spotify, while &lt;code&gt;Ctrl + &amp;lt;Scoll Lock / Print&amp;gt;&lt;/code&gt; will switch tracks.&lt;/li&gt;
&lt;li&gt;Tapping &lt;code&gt;Caps Lock&lt;/code&gt; doesn't do anything. Double Tapping &lt;code&gt;Caps Lock&lt;/code&gt; toggles Caps Lock. I've wasted way too much time backing up when I accidentally hit it AND eVERYTHING sTARTS tYPING lIKE tHIS.&lt;/li&gt;
&lt;li&gt;I use an older mechanical keyboard that doesn't have a Windows key, that I got for $2. I also religiously use Windows Virtual Desktops and the keyboard shortcuts for those are controlled with the Windows Key (Specifically &lt;code&gt;Windows + Tab&lt;/code&gt; brings up the overview). Google was my friend and I was able to rebind &lt;code&gt;Caps + Tab&lt;/code&gt; to open up the overview, and &lt;code&gt;Caps + &amp;lt;A/S&amp;gt;&lt;/code&gt; to switch between desktops. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Keyboard Shortcuts -- Learn 'Em. Love 'em. Live 'em.
&lt;/h2&gt;

&lt;p&gt;On top of everything I've configured for AutoHotkey, I swear by keyboard shortcuts. Why waste time reaching for the mouse and then moving it all the way across the screen to dig through 3 levels of menus to click on something, when you can just memorize the keyboard shortcut and be done with it.&lt;/p&gt;

&lt;p&gt;This is doubly true for Photoshop and Illustrator. All of the tools you're using have keyboard shortcuts to flip through them.&lt;/p&gt;

&lt;p&gt;You'll save so much time in the long run and you don't have to move your hand back and forth to the mouse as much. It's a win-win.&lt;/p&gt;

&lt;h1&gt;
  
  
  Go Forth And Automate!
&lt;/h1&gt;

</description>
      <category>discuss</category>
      <category>productivity</category>
      <category>automation</category>
    </item>
    <item>
      <title>Pausing CSS Animations on Hover</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Sat, 28 Mar 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/jackharner/pausing-css-animations-on-hover-4bi6</link>
      <guid>https://forem.com/jackharner/pausing-css-animations-on-hover-4bi6</guid>
      <description>&lt;p&gt;CSS Animations are an easy, lightweight way to add a little motion and excitement to a page. You definitely don't want to overdo it, though. One of the most frustrating things as a user is when you go to click on something, it moves, and you miss. Today I'm going to show you how to pause your CSS animations when someone goes to click on them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Animation
&lt;/h2&gt;

&lt;p&gt;We'll start with one of my favorite simple animations, the Pulse:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

@keyframes pulse {
  0% {
    transform: scale(1);
  }

  50% {
    transform: scale(1.1);
  }

  100% {
    transform: scale(1);
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;I've used that animation many times to emphasize a discount, bring focus to the best deal on a Pricing page, or even just to make a beating heart.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat Your Users Like Stormtroopers - Avoid Moving Targets
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthumbs.gfycat.com%2FClearDistortedFlies.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthumbs.gfycat.com%2FClearDistortedFlies.webp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If there are clickable things inside the thing you're animating, you don't want your users to have to click on moving targets. It's so frustrating to click and miss, let alone click, miss, and click on something else. Luckily, there's a really simple way to pause CSS Animations in CSS without JavaScript. The key to it all is the &lt;code&gt;animation-play-state&lt;/code&gt; property. Let's see it in (SCSS) action:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

.box {
  animation: pulse 3s infinite;

  &amp;amp;:hover {
    animation-play-state: paused;
  }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As you can see (&lt;a href="https://jackharner.com/blog/pausing-css-animations-on-hover/" rel="noopener noreferrer"&gt;Click Here for a Live Demo&lt;/a&gt;), it starts and stops the animation when you hover your mouse in and out of it.&lt;/p&gt;

&lt;p&gt;By setting the &lt;code&gt;animation-play-state&lt;/code&gt; to &lt;code&gt;paused&lt;/code&gt; on hover, the animation will pause, your click targets will stop moving, and your users will be happy. I had experimented with basically removing the animation on hover but that caused lots of jumps and skips. &lt;code&gt;animation-play-state&lt;/code&gt; literally just pauses the animation and un-pauses when you stop hovering.&lt;/p&gt;

&lt;p&gt;Super simple way to have more user-friendly animations on your site.&lt;/p&gt;

</description>
      <category>css</category>
      <category>ux</category>
      <category>ui</category>
      <category>animation</category>
    </item>
    <item>
      <title>Yarn vs. NPM - Package Manager Throwdown</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Sun, 19 Jan 2020 00:00:00 +0000</pubDate>
      <link>https://forem.com/jackharner/yarn-vs-npm-package-manager-throwdown-a3</link>
      <guid>https://forem.com/jackharner/yarn-vs-npm-package-manager-throwdown-a3</guid>
      <description>&lt;p&gt;NPM (Node Package Manager) and Yarn are both JavaScript based package managers for ease of installing 3rd Party Tools &amp;amp; Libraries into your modern web development workflow. They revolutionized the way people shared code. Instead of having to tediously copy and paste, or even worse, link to a hosted version of the library, now you fetch a library or module and store it locally in your project. Yarn and NPM work fairly similarly, but have a few key differences in how they operate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Major Differences Between Yarn &amp;amp; NPM
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;NPM was developed as an open source project in 2009. Yarn was released by Facebook in 2016 as an improvement upon the foundation that NPM laid.&lt;/li&gt;
&lt;li&gt;Yarn uses &lt;code&gt;yarn add&lt;/code&gt; while NPM uses &lt;code&gt;npm install&lt;/code&gt; (Can be confusing when switching between the two.)&lt;/li&gt;
&lt;li&gt;Yarn keeps a copy of packages you download stored locally. I'll explain why in a little bit.&lt;/li&gt;
&lt;li&gt;Both Yarn and NPM use the &lt;code&gt;package.json&lt;/code&gt; file to get the packages to install. However, Yarn uses &lt;code&gt;yarn.lock&lt;/code&gt; and NPM uses &lt;code&gt;package-lock.json&lt;/code&gt; to more explicitly state which package version to get.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A Breif History of NPM
&lt;/h2&gt;

&lt;p&gt;NPM was originally released back in January 2010 by Isaac Z. Schlueter and took the JavaScript world by storm. It was the inspiration for Yarn, developed by Facebook in 2016, PHP's package manager Composer, and more. Due to the popularity of the project they eventually incorporated as npm, inc in order to manage enterprise level relationships to ensure the success of the project and the JavaScript community as a whole.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yarn Module Cache
&lt;/h2&gt;

&lt;p&gt;Every time you install a new package with Yarn, it stores a copy of it locally on your computer. This way when multiple projects require the same package, Yarn doesn't have to go download the required package again, it just grabs it off your hard drive and puts it in the project you're installing, saving you time and bandwidth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blazing Saddles: Package Manager Boogalo
&lt;/h2&gt;

&lt;p&gt;According to a test done by &lt;a href="https://github.com/appleboy/npm-vs-yarn"&gt;GitHub user appleboy&lt;/a&gt; that you can reproduce yourself, Yarn both with and without it's cache is significantly faster at installing modules, and even installs without internet! (assuming you've cached the package you're installing).&lt;/p&gt;

&lt;p&gt;Here are the results of their test comparing NPM to Yarn:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test&lt;/th&gt;
&lt;th&gt;npm install&lt;/th&gt;
&lt;th&gt;npm ci&lt;/th&gt;
&lt;th&gt;yarn&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;install without cache (without node_modules)&lt;/td&gt;
&lt;td&gt;3m&lt;/td&gt;
&lt;td&gt;3m&lt;/td&gt;
&lt;td&gt;1m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;install with cache (without node_modules)&lt;/td&gt;
&lt;td&gt;1m&lt;/td&gt;
&lt;td&gt;18s&lt;/td&gt;
&lt;td&gt;30s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;install with cache (with node_modules)&lt;/td&gt;
&lt;td&gt;54s&lt;/td&gt;
&lt;td&gt;21s&lt;/td&gt;
&lt;td&gt;2s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;install without internet (with node_modules)&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;2s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Blazing Fast! Even without using a cache, Yarn is 200% faster than NPM.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Install Yarn
&lt;/h2&gt;

&lt;p&gt;After doing the research for this post I'm definitely sticking to Yarn for projects moving forward. Here's how you can install Yarn and see for yourself just how fast it is and get started integrating it into your workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;

&lt;p&gt;Go to the &lt;a href="https://classic.yarnpkg.com/en/docs/install"&gt;Yarn Installation Page&lt;/a&gt;, make your you have Node.js installed, download the version you want and run the installer. Yarn goes through and installs for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  macOS
&lt;/h3&gt;

&lt;p&gt;You can install Yarn with HomeBrew:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ubuntu / Linux
&lt;/h3&gt;

&lt;p&gt;Go to the &lt;a href="https://classic.yarnpkg.com/en/docs/install"&gt;Yarn Installation Page&lt;/a&gt; and follow the steps. You'll have to add Yarn's repo to APT and then install through there.&lt;/p&gt;

&lt;h3&gt;
  
  
  NPM - Don't Do This
&lt;/h3&gt;

&lt;p&gt;You can even install Yarn with NPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --global yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Although, for security reasons that I don't fully understand they recommend NOT installing Yarn through NPM and instead installing Yarn based on your specific operating system (&lt;a href="https://classic.yarnpkg.com/en/docs/install#debian-stable"&gt;Ubuntu/Debian&lt;/a&gt;, &lt;a href="https://classic.yarnpkg.com/en/docs/install#mac-stable"&gt;Mac&lt;/a&gt;, &lt;a href="https://classic.yarnpkg.com/en/docs/install#windows-stable"&gt;Windows&lt;/a&gt;).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Are you going to make the switch?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Let me know on twitter &lt;a href="https://twitter.com/jackharner"&gt;@JackHarner&lt;/a&gt; if you do and which package manager you prefer! Thanks for reading!!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>node</category>
      <category>npm</category>
      <category>yarn</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Auto-Generate Content Folders In Gatsby</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Sun, 22 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://forem.com/jackharner/auto-generate-content-folders-in-gatsby-344f</link>
      <guid>https://forem.com/jackharner/auto-generate-content-folders-in-gatsby-344f</guid>
      <description>&lt;p&gt;My portfolio &lt;a href="https://jackharner.com"&gt;JackHarner.com&lt;/a&gt; is built with Gatsby, a framework based on React that makes blazing fast websites.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IYHWNxx3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tmryutffhcsyimmydcjv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IYHWNxx3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tmryutffhcsyimmydcjv.png" alt="Gatsby Logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have my Blog and Portfolio content setup as a couple of directories with subdirectories for the individual posts. Like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
| ...
| content/
  | blog/
    | blog-post/
      | index.md
      | featuredImage.png
      | ...
    | blog-post-2/
      | index.md
      | featuredImage.png
      | ...
    | ...
  | portfolio/
    | ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each of the &lt;code&gt;index.md&lt;/code&gt; files contains a block of frontmatter dsecribing attributes about the post.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
date: 2019-12-22T18:23:53.017Z
title: "Auto-Generate Content Folders In Gatsby" 
subtitle: "Preformat Your Frontmatter &amp;amp; More"
featuredImage: "./featuredImage.png"
tags: ['Gatsby', 'Node']
externalLink: ""
published: true
--------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All of these folders and files are then parsed at build time to generate the pages and the content throughout the site.&lt;/p&gt;

&lt;p&gt;As some of you may know, I'm very lazy, but lazy in the good way where I don't like doing repetitive tasks more than once or twice. I've automated tons of simple tasks in my day to day at &lt;a href="https://jackharner.com/portfolio/shoolu/"&gt;Shoolu&lt;/a&gt;. Things like running reports, and processing product photos are all now 1-2 click tasks, when they used to take hours out of my day every week.&lt;/p&gt;

&lt;p&gt;I wanted starting a new blog post or portfolio piece to be as simple as possible, and with this I've gotten it down to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run newBlog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at how I did it and how you can speed up a small part of updating your Gatsby site with Node.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the Template Directory
&lt;/h2&gt;

&lt;p&gt;Create a new directory in your &lt;code&gt;/src/content/&lt;/code&gt; folder called &lt;code&gt;templates/&lt;/code&gt;. Inside your new &lt;code&gt;templates/&lt;/code&gt; directory create a new directory for every post type you want to automate. In my case it will be &lt;code&gt;blog/&lt;/code&gt; and &lt;code&gt;portfolio/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now your project should look a little something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
| ...
| content/
  | blog/
    | ...
  | portfolio/
    | ...
  | templates/
    | blog/
      | &amp;lt;empty folder&amp;gt;
    | portfolio/
      | &amp;lt;empty folder&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Get Template-ing
&lt;/h2&gt;

&lt;p&gt;This is where you'll need to customize this tutorial to fit with your site and preexisting content. Inside your &lt;code&gt;/src/content/templates/&amp;lt;post-type&amp;gt;&lt;/code&gt; directory, create versions of the files you will need every time you create a post. For me, that includes an &lt;code&gt;index.md&lt;/code&gt; file with some custom frontmatter, and a &lt;code&gt;featuredImage.png&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Take a look at my &lt;code&gt;templates/blog/index.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--------
date: $date
title: "$title" 
subtitle: ""
featuredImage: "./featuredImage.png"
tags: ['']
externalLink: ""
published: false
--------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;$date&lt;/code&gt; and &lt;code&gt;$title&lt;/code&gt; variables in the frontmatter. We will be replacing those variables down the line.&lt;/p&gt;

&lt;p&gt;My default Featured Image is just a solid pink image to match the branding of the site:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--94olYske--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jackharner.com/static/124be52bbf346d8c60c354150e3cbdd7/c1b63/defaultFeaturedImage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--94olYske--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jackharner.com/static/124be52bbf346d8c60c354150e3cbdd7/c1b63/defaultFeaturedImage.png" alt="Default Featured Image" title="Default Featured Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Featured Image is pretty much always going to be changed down the line. One problem I've run into is that Gatsby, as far as I know, doesn't allow you to set default Frontmatter values. However, having the default allows me to not have to remember "featuredImage.png" when saving the updated image (I can just overwrite the default).&lt;/p&gt;

&lt;h2&gt;
  
  
  Script All The Things!
&lt;/h2&gt;

&lt;p&gt;Now that we've got our template, we're going to write a Node script that copies the folder and replaces some variables with user input.&lt;/p&gt;

&lt;p&gt;We do need a few dependencies so run this command in your projects root folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i --save-dev readline-sync ncp replace-in-file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;readline-sync&lt;/code&gt; allows for super simple Node CLI Prompts to take in user input.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ncp&lt;/code&gt; is a tool to help Node copy folders recursively.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;replace-in-file&lt;/code&gt; makes it really easy to substitute values for defined variables in the copied version of the file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the root folder for the project, create a new directory called &lt;code&gt;tools/&lt;/code&gt; and in that a new file called &lt;code&gt;newBlog.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;At the top of &lt;code&gt;newBlog.js&lt;/code&gt; declare all of the dependencies we'll need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var readline = require('readline-sync');
var ncp = require('ncp').ncp;
var replace = require('replace-in-file');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next up is to define some variables we are going to use and take in the User Input for Title &amp;amp; Slug:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var postTitle = readline.question("What is the title? ");
var slug = readline.question("Slug? [Default: '"+ string_to_slug(postTitle) +"'] ", {defaultInput: string_to_slug(postTitle)});
var date = new Date().toISOString();

var sourcePath = "./src/content/templates/blog/";
var destPath = "./src/content/blog/" + slug;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By setting a default value for the Slug allows me to set the slug to something other than the default, if I want to. Otherwise it just sets it to a url-encoded version of the title.&lt;/p&gt;

&lt;p&gt;Generating the default slug from the given title is done with the following function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function string_to_slug(str) {
    str = str.replace(/^\s+|\s+$/g, ''); // trim
    str = str.toLowerCase();

    // remove accents, swap ñ for n, etc
    var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
    var to = "aaaaeeeeiiiioooouuuunc------";
    for (var i=0, l=from.length ; i&amp;lt;l ; i++) {
        str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
    }

    str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
        .replace(/\s+/g, '-') // collapse whitespace and replace by -
        .replace(/-+/g, '-'); // collapse dashes

    return str
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It takes in a string, removes whitespace, converts non url-encoded characters, and replaces spaces with &lt;code&gt;-&lt;/code&gt; dashes. ("What's Up Fool?" -&amp;gt; "whats-up-fool").&lt;/p&gt;

&lt;h2&gt;
  
  
  Time To Copy
&lt;/h2&gt;

&lt;p&gt;Since everything is set up, it's time to copy the directory. We use &lt;code&gt;ncp&lt;/code&gt; which is a Node package to replicate Linux's &lt;code&gt;cp&lt;/code&gt; command. It takes in the Source Folder, the Destination Folder, and a Callback as arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ncp(sourcePath, destPath, (err) =&amp;gt; {
    if (err) {
      return console.error(err);
    }
    console.log('Done Copying');

    // ... Do Stuff After Copying Is Done
   });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Replace The Template Variables
&lt;/h2&gt;

&lt;p&gt;Remember the &lt;code&gt;$date&lt;/code&gt; and &lt;code&gt;$title&lt;/code&gt; variables from earlier? Now it's time to swap those out for real values. Using the &lt;code&gt;replace-in-file&lt;/code&gt; Node Package makes this super simple.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;replace()&lt;/code&gt; function takes in an Options Object and a callback. Here's our Options Object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var replaceOptions = {
    files:[destPath + "/index.md"],
    from: [/\$title/g, /\$date/g],
    to: [postTitle, date],
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Define the files to search in, the keys to search for (can be Regex or just a string), &amp;amp; what to replace them with then &lt;code&gt;replace-in-file&lt;/code&gt; does all the heavy lifting. If you pass in an array to both &lt;code&gt;from&lt;/code&gt; and &lt;code&gt;to&lt;/code&gt; it will replace the first key in the &lt;code&gt;from&lt;/code&gt; array to the first value in the &lt;code&gt;to&lt;/code&gt; array, and so on, allowing you to replace multiple things in one go.&lt;/p&gt;

&lt;p&gt;All that's left is to pass in our options and the callback function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;replace(replaceOptions, (error, changedFiles) =&amp;gt; {
    if (error) {
      return console.error('Error occurred:', error);
    }
    console.log('Modified files:', changedFiles.join(', '));
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Code, Comments, ACTION!
&lt;/h2&gt;

&lt;p&gt;You have two options when it comes to actually running the script.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Just run the script with Node: &lt;code&gt;$ node tools/newBlog.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;node tools/newBlog.js&lt;/code&gt; to your &lt;code&gt;package.json&lt;/code&gt; as a script and run it through NPM (i.e. &lt;code&gt;$ npm run newBlog&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then enter a title, optionally pick a slug and away we go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Where To Go From Here?
&lt;/h2&gt;

&lt;p&gt;If you wanted to take this script a few steps further, here are some ideas to get you started.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duplicate your &lt;code&gt;tools/newBlog.js&lt;/code&gt; file for every other post type, modifying as necessary. &lt;/li&gt;
&lt;li&gt;Refactor the script to be able to handle any post type you throw at it. &lt;code&gt;readline-sync&lt;/code&gt; has a whole lot of options for taking in user input. &lt;/li&gt;
&lt;li&gt;Create as much content as possible, and automate as many things as possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://twitter.com/jackharner"&gt;Hit me up on Twitter&lt;/a&gt; if you implement this script in your Gatsby site! I'd love to hear your suggestions.&lt;/p&gt;

&lt;h2&gt;
  
  
  If You're Lazy, Here's the full script:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var readline = require('readline-sync');
var ncp = require('ncp').ncp;
var replace = require('replace-in-file');

var postTitle = readline.question("What is the title? ");
var slug = readline.question("Slug? [Default: '"+ string_to_slug(postTitle) +"'] ", {defaultInput: string_to_slug(postTitle)});
var date = new Date().toISOString();

var sourcePath = "./src/content/templates/blog/";
var destPath = "./src/content/blog/" + slug;

var replaceOptions = {
    files:[destPath + "/index.md"],
    from: [/\$title/g, /\$date/g],
    to: [postTitle, date],
} 

ncp(sourcePath, destPath, (err) =&amp;gt; {
    if (err) {
      return console.error(err);
    }
    console.log('Done Copying');
    replace(replaceOptions, (error, changedFiles) =&amp;gt; {
        if (error) {
          return console.error('Error occurred:', error);
        }
        console.log('Modified files:', changedFiles.join(', '));
      });
   });

function string_to_slug (str) {
    str = str.replace(/^\s+|\s+$/g, ''); // trim
    str = str.toLowerCase();

    // remove accents, swap ñ for n, etc
    var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;";
    var to = "aaaaeeeeiiiioooouuuunc------";
    for (var i=0, l=from.length ; i&amp;lt;l ; i++) {
        str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
    }

    str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
        .replace(/\s+/g, '-') // collapse whitespace and replace by -
        .replace(/-+/g, '-'); // collapse dashes

    return str;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>gatsby</category>
      <category>automation</category>
      <category>node</category>
    </item>
    <item>
      <title>I've Forked The Repo, Now What?</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Mon, 04 Nov 2019 20:14:15 +0000</pubDate>
      <link>https://forem.com/jackharner/i-ve-forked-the-repo-now-what-4fk2</link>
      <guid>https://forem.com/jackharner/i-ve-forked-the-repo-now-what-4fk2</guid>
      <description>&lt;h2&gt;
  
  
  Syncing Your Repo With the Upstream Repo
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://jackharner.com/blog/sync-forked-repo/"&gt;JackHarner.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, you want to make some changes to an Open Source Repo? Good for you. That's the beauty of Open Source, even just fixing typos in the documentation makes a difference. Today I'm going to walk you through keeping your copy of a repo up to date with changes pushed to the original repo. &lt;/p&gt;

&lt;p&gt;This tutorial assumes: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have a basic understanding of git&lt;/li&gt;
&lt;li&gt;You have a forked repo&lt;/li&gt;
&lt;li&gt;The original repo has changes that you want in your forked repo&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up The Remote
&lt;/h2&gt;

&lt;p&gt;The first thing you want to do is add the Original Repo as a remote of your Forked Repo. From the command line you want to move into your project directory and add the Original Repo's clone URL as the &lt;code&gt;upstream&lt;/code&gt; remote.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="o"&gt;{{&lt;/span&gt;project_name&lt;span class="o"&gt;}}&lt;/span&gt;
git remote add upstream &lt;span class="o"&gt;{{&lt;/span&gt;original_repo_url&lt;span class="o"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Repo URL can be found on the Repo page on Github. Click on the &lt;code&gt;Clone or download&lt;/code&gt; button and make sure it says "Clone with HTTPS" since you don't have write access to the Original Repo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yqbddPPm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/harnerdesigns/jackharner-gatsby/master/src/content/blog/sync-forked-repo/remote_url.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yqbddPPm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/harnerdesigns/jackharner-gatsby/master/src/content/blog/sync-forked-repo/remote_url.jpg" alt="Original Repo URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can verify your remotes with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which should output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;origin  git@github.com:{{you}}/{{project_name}}.git (fetch)
origin  git@github.com:{{you}}/{{project_name}}.git (push)
upstream    https://github.com/{{owner}}/{{project_name}}.git (fetch)
upstream    https://github.com/{{owner}}/{{project_name}}.git (push)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Go Get That Code!
&lt;/h2&gt;

&lt;p&gt;Now that we've associated our Original Repo with our local Forked Repo, it's time to go get the new code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch upstream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;git fetch&lt;/code&gt; gets the changes to the remote repo without changing any of the files in your local version. It essentially lets you see what everyone else has done to the code without making any changes to yours. You should see it pull down a bunch of different branches, tags, and some file changes. &lt;/p&gt;

&lt;p&gt;To apply the new changes to your repo make sure you're on the branch you want to pull in (in our case &lt;code&gt;master&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then pull the matching branch from the &lt;code&gt;upstream&lt;/code&gt; remote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git pull upstream master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will asks you for a message for the merge commit. You can usually just leave the default and just save with &lt;code&gt;CTRL + X&lt;/code&gt;. Git finishes up the merge commit, and your Local Repo is now up to date with the Original. &lt;/p&gt;

&lt;h2&gt;
  
  
  Seal The Deal
&lt;/h2&gt;

&lt;p&gt;Finish off your changes by pushing them back up to your Forked Repo's &lt;code&gt;origin&lt;/code&gt; remote that you have write access to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ta da! You just refreshed your forked repo. Make, test, commit and push your changes and you'll be all set to create a pull request back to the Original Repo. You're ready to start changing the world of Open Source Software one pull request at a time! &lt;/p&gt;

</description>
      <category>git</category>
      <category>opensource</category>
      <category>codenewbie</category>
      <category>beginners</category>
    </item>
    <item>
      <title>What Else Does This Landing Page Need?</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Thu, 11 Jul 2019 21:03:10 +0000</pubDate>
      <link>https://forem.com/jackharner/what-else-does-this-landing-page-need-4d68</link>
      <guid>https://forem.com/jackharner/what-else-does-this-landing-page-need-4d68</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P3iJIl5G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/gh5ljvvanzjrz1t4ikk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P3iJIl5G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/gh5ljvvanzjrz1t4ikk0.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm working on the Rewards Program landing page for work, and I'm curious what Dev.to thinks it needs or what could be better, etc. &lt;/p&gt;

&lt;h2&gt;
  
  
  My Thoughts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Instead of having a "Sign Up" and "Sign In" button that have equal weight, just having a "Sign Up" button with an "Already Have An Account? Sign In" Link under it. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Including a slider of cards that include the things you can earn points for and what you can redeem points for.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;FAQ section.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Any other suggestions/comments?
&lt;/h2&gt;

&lt;p&gt;Thank you for your time and feedback.&lt;/p&gt;

</description>
      <category>help</category>
      <category>feedback</category>
      <category>discuss</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Sick Console Bro! How To Style Your console.log with CSS</title>
      <dc:creator>Jack Harner 🚀</dc:creator>
      <pubDate>Mon, 17 Jun 2019 19:38:43 +0000</pubDate>
      <link>https://forem.com/jackharner/sick-console-bro-how-to-style-your-console-log-with-css-198l</link>
      <guid>https://forem.com/jackharner/sick-console-bro-how-to-style-your-console-log-with-css-198l</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally Posted On &lt;a href="https://harnerdesigns.com/blog/style-your-console-log-with-css/" rel="noopener noreferrer"&gt;Harner Designs&lt;/a&gt; | Photo by &lt;a href="https://unsplash.com/@glenncarstenspeters?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Glenn Carstens-Peters&lt;/a&gt; on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://developers.google.com/web/tools/chrome-devtools/console/console-write#styling_console_output_with_css" rel="noopener noreferrer"&gt;Chrome&lt;/a&gt; and Firefox (&amp;gt;31) you can add CSS styles to your console.log() messages. It's fairly simple and straightforward. &lt;/p&gt;

&lt;p&gt;All you need to do is include a &lt;code&gt;%c&lt;/code&gt; string before your log message and then pass your CSS as a parameter to the console.log( ) function. Like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%c{{Log Message}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{CSS}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, this code runs on &lt;a href="https://harnerdesigns.com" rel="noopener noreferrer"&gt;my portfolio&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cHarner Designs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color:#233E82; font-family:'Ubuntu'; display: block;font-weight:bold; font-size:48px; background:#fff;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cLike to dig into the meaty bits of the website?&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Thanks for looking! Hit us up on Twitter @harnerdesigns!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color:#222; font-family:'Ubuntu'; font-weight:100; font-size:24px; background:#fff;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cDid you know you can style your console output?!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color:#333; font-family:'Ubuntu'; font-weight:100; font-size:18px; background:#fff;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cCheck our blog to learn how: https://harnerdesigns.com/blog/style-your-console-log-with-css/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line-height: 3em; padding: 0.5em; text-align: center; border: 1px dotted #aaa; background:#fff; font-size: 14px;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and outputs like this to the console: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fharnerdesigns.com%2Fwp-content%2Fuploads%2F2019%2F06%2Fstyled-console-update.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fharnerdesigns.com%2Fwp-content%2Fuploads%2F2019%2F06%2Fstyled-console-update.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Styling Multiple Strings In One Log
&lt;/h2&gt;

&lt;p&gt;It's also &lt;a href="https://stackoverflow.com/a/13017382/10425698" rel="noopener noreferrer"&gt;possible&lt;/a&gt; to include multiple strings in one command and style them differently. Check it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cString1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cString2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{CSS for String1}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{CSS for String2}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reusing Styles Across Log Messages
&lt;/h2&gt;

&lt;p&gt;You can also store the CSS You want to apply to a variable and then pass that to multiple console.logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;consoleStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{Reusable CSS}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cString1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;consoleStyle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cString2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;consoleStyle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Do you leave any little easter eggs in your console? Could you see a use case for this in your own projects? I'd love to know down in the comments! Show me some examples of cool things you've found in console messages. &lt;/p&gt;

&lt;h2&gt;
  
  
  Recent Blog Posts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://harnerdesigns.com/blog/anatomy-of-a-wordpress-theme/" rel="noopener noreferrer"&gt;Anatomy of a WordPress Theme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://harnerdesigns.com/blog/add-logout-link-to-account-menu-bigcommerce-for-wordpress/" rel="noopener noreferrer"&gt;Add Logout Link To Account Menu – BigCommerce For WordPress&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://harnerdesigns.com/blog/measure-angles-in-illustrator/" rel="noopener noreferrer"&gt;How To Measure Angles In Illustrator&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>css</category>
    </item>
  </channel>
</rss>
