Do I Need to Learn React to Build Gutenberg Blocks?

The question of the day is: Do I need to learn React in order to build a Gutenberg block?

The short answer is no. You don’t need to know anything about React to build a Gutenberg block. The reason why is because WordPress has done a great job of abstracting away React and the foundational tools that it’s used to create Gutenberg. WordPress has created its own API that you can use in order to create your blocks.

The Real Answer

I remember back when I first started working with WordPress and I would meet other people who were WordPress developers and I would ask them how long they had been working with PHP. More often than not, the response would be “what’s PHP?”.  I was astounded that they would call themselves WordPress developers and actually be building things without any knowledge of PHP. Some of those people are what we now call site builders, but many were actually customizing themes.  The reality is that they just learned the syntax. They learned what PHP tags were and knew what template tags they could drop into them to customize a pre-existing theme. Now they couldn’t create a theme from scratch, but they could use a starter theme approach.

Thinking about Gutenberg development, do you want to be that Gutenberg developer that doesn’t know React?  If you understand the foundational tools, you’ll be able to do a lot more. Without understanding the technology that is underlying Gutenberg and how it works, it is going to limit your ability to create Gutenberg blocks and limit your imagination of what you can do with Gutenberg. This is why I think it’s important to know React.

What is React?

React is basically Facebook’s view library. The way it works is you pass properties down into a view, typically called a component, and the view will be rendered based on those properties. You can also pass event handlers as properties that will allow you to make your views interactive as well.  Because of the way that you typically make React components in ES6, you would also use something called JSX.  JSX is a syntax that Facebook created for React that looks a lot like HTML. React has some great documentation on JSX, so I’d recommend you take a look at those.

What is Redux?

Another thing you’ll probably want to learn more about is Redux, which is a state management library that is commonly used with React.  WordPress uses Redux behind the scenes for its data store. Redux is essentially a state management library.  Reach and Redux work together quite well. When an action takes place in the Gutenberg editor, an event is triggered that goes through Redux and updates the global state for the editor.  Any change in this global state will automatically signal to the React view layers that specific properties have changed and any component dependent on those properties will be automatically re-rendered.

What Should I Learn?

My recommendation is to learn ES6, JSX, React and Redux… in that order. This will set you on the path to learning to develop Gutenberg blocks using modern JavaScript.

When you are starting out, I’d recommend checking out Create Guten Block. This will have all the tooling for creating Gutenberg blocks with all of these modern tools. After you get more familiar with how things work, I’d recommend running the “eject” command in Create Guten Block and starting to learn Webpack and more about how the build process is set up.

Resources You Should Check Out

Surfacing Gutenberg Blocks in the WordPress REST API

The beauty of Gutenberg is that the HTML content is more structured and semantic while also simplifying the user experience. All of the data is stored in the post content, which is also great because we don’t have to request a bunch of post meta to render the page. On the other hand, if nothing is stored in post meta, how do you fetch this structured block data via the WordPress REST API?

When Gutenberg loads up blocks in the JavaScript, it actually parses your HTML to find the data it needs. So what do you do when you want to fetch that data in PHP?

Well, the comments that Gutenberg outputs in your post’s HTML are so Gutenberg can parse out your block’s data in PHP. The attributes in those comments aren’t necessarily used by Gutenberg in JavaScript. It is a redundant output so that PHP can parse your block data.

All you need to do to parse Gutenberg generated content into block data in PHP is use the gutenberg_parse_blocks() function. Just pass your content to that function and you will get back a JSON data structure representing the Gutenberg blocks on your page.

So how do we surface all that block data in the WordPress REST API?

Like so:

This will hook into the rest_api_init action and add our closure as a callback. We start by getting all post types that support the editor. Then, for each post type, we call gutenberg_can_edit_post_type()to check if our post type actually supports Gutenberg. If it does, we use the register_rest_field() function to add a blocksproperty to the object returned by the WordPress REST API. The get_callback bit is all we really need to declare since we are only concerned with outputting the blocks in the API. That get callback need only return a call to gutenberg_parse_blocks() after passing in the raw post content for the requested post.

WordPress and the Open-Closed Principle

Oftentimes we think of the SOLID principles of object-oriented programming as just that: object-oriented programming principles. However, we are going to take a closer look at the second principle, the open-closed principle, and see how it applies to WordPress.

You are probably thinking, “WordPress isn’t really object-oriented”… and you’d be mostly right. Much of WordPress is functional, although there are still plenty of objects to be found. I’m not talking about objects or entities within WordPress though. I’m talking about WordPress as a whole.

Flashback

I remember the first time I installed Magento. It took me a while and certainly wasn’t as easy as WordPress’ famous 5-minute install. I also remember the first time I tried to install an extension for Magento. I had to copy a folder to a certain location, edit a core file to make sure the extension loaded, change a setting over here… wait… yes, I said it: “edit a core file”!

Once I tried out WordPress and saw how easy it was to install a plugin, I was hooked. No crazy installation instructions and no chance that I could break my entire WordPress install because I failed to properly edit a core file.

The Open-Closed Principle

Objects or entities should be open for extension, but closed for modification.

The open-closed principle basically says that an object or entity (or system) should be open for extension and closed for modification. If you think about it, this is the real beauty of WordPress’ plugin system.

  • WordPress is closed for modification.
    WordPress core is stable, backward compatible and not meant to ever have core files edited.
  • WordPress is open for extension.
    Simply install a plugin and you can easily extend WordPress to have additional functionality.

I’d dare say that the ease of installing plugins is a big part of what propelled WordPress forward in its earlier days. The ability for a user to do what previously required a developer to do was just magical. The real key here though is that a plugin would never break WordPress in an irreversible way. If the extension breaks the system, just disable it and return to a stable core.

If we take WordPress as an example, I think it is safe to say that the open-closed principle is worth implementing. Thanks to WordPress’ hook system, all the plugins we write can also benefit from this concept. All you need to do is add a few key actions or filters to your plugin to make it extensible.

In what ways have you used the open-closed principle (perhaps even inadvertently)?

Advice for New Programmers

I’ve been a programmer for just over a decade now and have always shared and taught others as I’ve learned. However, much of that information has never really been documented except in the form of videos from talks at conferences. I want to take some time to offer a few tips to those who are just starting out.

Set Goals

When you first start out in a new field, you often have no plan for where you want to end up. You are too focused on learning as much as you can to have time for setting goals. This is a big mistake. Programming is a very broad and deep field with many distractions along the way. Allow your passions to guide your goals. Write your goals down where you will see them every day. Without a goal, strategy and action will only get you closer to where you probably don’t want to be.

Beware Opportunity Costs

The field of economics teaches us about the concept of opportunity costs. An opportunity cost is the loss of potential gain from one opportunity because you were focused on pursuing a different opportunity.  We see this when, for example, we choose to pursue a specific technology or framework only to have another technology or framework beat it out and become the industry standard. We could have become a pro in the thing that is now an industry standard, but instead, we are behind the times because we chose “the wrong thing”.

The same thing applies to your everyday work. We choose to focus on “getting the job done” and not on packaging up our code for reuse. What is the opportunity cost? A loss of time the next time we have a similar task. Those opportunity costs add up fast and before long if you had just invested a bit of time here and there you could have bought yourself time to come up for air and learn that new industry standard tool.

Invest in Yourself

If you have a mediocre skill set, you are unremarkable. People want to hire remarkable people and the best thing you can do is invest in your skillset. This could be investing money in a training course or time in tackling a side project just for the purpose of learning. Regardless, the key is that you keep learning and keep growing. The second you stop doing that, you slow down your pace and start falling behind.

Many people argue that they don’t have time to invest in learning new things because they are so busy. That is a cop-out.  See the section above on opportunity costs and invest in learning how to leverage the work you’ve already done to buy yourself some time. You are a programmer.  Automation and code reuse are key.

Focus on What Doesn’t Change

Most people are always focused on where the industry is heading, what the latest technologies are and the latest frameworks that are available. However, there is a lot that doesn’t change. The foundational concepts behind programming are the same, regardless of the programming language or syntax. Understanding how to modularize and reuse your code isn’t going out of style. Mastering the common design patterns is a useful endeavor.

Learning the new things is important, but if you spend more time learning the newest tools and not the foundational principles… you aren’t going to pick up the new things as quickly.

Work from your Strengths

Everyone has things they do well and things that they don’t. Often, your strengths will align with your passions. Learn early on what you like and what you are good at. If you want, create a Venn diagram to see where the two overlap. This is where you want to go deep. Learn as much as you can and become as awesome as you can in those areas. These are the skills that make you marketable. These are the things you will be excited about, do well and have your clients (or boss) raving about. Learning new things for the purpose of rounding out your skillset is important too, but never neglect your strengths.

Shorten Your Feedback Loops

Any time you write code, you want to keep your feedback loop as short as possible. For example, when I first started coding, I would use FTP to upload my files after each change. The process was to edit a file, save the file, upload the file, check the browser to see if the change worked. Then, I started doing local development. The process was then to edit a file, save the file and then check the browser. The time-consuming step of uploading the file was now gone. I had made my feedback loop shorter. I knew quicker if the change I made had worked or not.

The basic concepts of programming are the same across all languages. However, Java is a compiled language and you have to wait for the code to “build” before you can run it. On the other hand, you can code JavaScript in your browser and watch it run the second you press enter. Which do you think you would learn the fastest?

Keep it Simple

Once you learn how to architect software solutions, leverage object-oriented programming or work with dependency injection containers you are going to see opportunities to use these new skills everywhere. Don’t! Just because you are holding a hammer, it doesn’t mean that everything is a nail. Never introduce complexity into a system just so you can use your new hammer.

On that note, I will close by recommending a book that I think all new developers should read: Code Simplicity. There are no code examples, so it is a good read regardless of what programming language you are learning. The focus of this book is to help you avoid complexity, and thus much difficulty as your code progresses over time.

Conclusion

Those are just a few of the things I’ve learned along the way and think are important. The most important things you will learn in this field have nothing to do with the syntax of a programming language or the latest tool. Technology is constantly changing. The challenge is identifying and acting on those things that will really make a long-term difference.

If you are a seasoned software developer, what bits of advice would you offer a new developer?

Creating a Better WordPress Loop

The WordPress loop is ubiquitous. It is one of the first things you learn as a WordPress developer and it is something you must know the intricacies of in order to avoid causing problems. I’ve dreamt of a day when the WordPress loop and all its various implementations are no longer necessary. Today, I would like to demonstrate how we can leverage a simple PHP generator to create a better WordPress loop.

Complexities of the WordPress Loop

At the moment, there are a few things that make the WordPress loop more complicated than it really has to be:

  1. The WordPress loop works differently if you are looping over the global query or have a separate instance of WP_Query. It is also very different if you just have an array of posts and want to loop through those.
  2. You have to remember to reset the post data after running secondary loops to avoid causing issues with the context of global variables after your loop.
  3. You have to remember to call the_post() function (or method) within each iteration of the loop.
  4. There is no the_post() function when looping through an array of posts, only setup_postdata() which means the global $post object is never set in that scenario unless you handle it yourself. As such, many functions that depend on the $post global simply don’t work (e.g. the_title(), the_excerpt(), etc.).

It doesn’t have to be this way. We can solve these issues and have a better WordPress loop.

The Beauty of a Generator

This is the background behind my code and why a generator is an elegant approach to creating a better WordPress loop. Don’t care? Skip to the results.

Getting Started

A generator is, first and foremost, a function. So let’s start by giving it a name and setting up the parameters.

/**
 * Simplifies the WordPress loop.
 * 
 * @param WP_Query|WP_Post[] $iterable
 */
function wp_loop( $iterable = null ) {

}

We’ll call our function wp_loop() since that is what it handles. As you can see, it allows an iterable to be passed as a parameter. The default is that no iterable is required. What is an iterable? Essentially it is an array or anything that implements the Traversable interface. In our case, it will either be a WP_Query instance or an array of WP_Post objects. While WP_Query doesn’t technically implement the Traversable interface, we’re just going to fetch the array of posts from it… so for all intensive purposes, it is an iterable.

In the event that an iterable isn’t provided, we want to default to using the global WP_Query object:

/**
 * Simplifies the WordPress loop.
 *
 * @param WP_Query|WP_Post[] $iterable
 */
function wp_loop( $iterable = null ) {

   if ( null === $iterable ) {
      $iterable = $GLOBALS['wp_query'];
   }

}

Lowest Common Denominator

In order for our function to loop through an array of posts just the same as it would a WP_Query instance, we’ll use a “lowest common denominator” version of the loop… the approach you would use to loop through an array of posts.

This is the traditional way to loop through an array of posts:

foreach ( $posts as $post ) {
   setup_postdata( $post );
   // Do stuff here
}
wp_reset_postdata();

The only problem with this approach is that the global $post object isn’t properly set as it would be if you looped through a WP_Query instance. To resolve this, we’d have to handle setting the global post object ourselves:

global $post;

// Save the global post object so we can restore it later
$save_post = $post;

foreach ( $posts as $post ) {
   setup_postdata( $post );
   // Do stuff here
}
wp_reset_postdata();

// Restore the global post object
$post = $save_post;

Data Validation

OK, so we have a plan. Before we add this code to our function, let’s make sure our function always has an array of posts:

$posts = $iterable;
if ( is_object( $iterable ) && property_exists( $iterable, 'posts' ) ) {
   $posts = $iterable->posts;
}

We are assuming our iterable is an array of posts and setting the $posts variable to be equal to the iterator. Otherwise, if the iterator is a query, it will have a posts property we can fetch the posts from. I intentionally don’t check to see if the iterable is an actual WP_Query object so that the function becomes more flexible. It can take any object where there is a posts property.

What happens if someone passes in an invalid value to the function? Good point… let’s add some error checking.

if ( ! is_array( $posts ) ) {
   throw new \InvalidArgumentException( sprintf( 'Expected an array, received %s instead', gettype( $iterable ) ) );
}

Great! Now our function will throw an exception if it receives an invalid value.

Generator Magic

Let’s take a look at what our code looks like now if we put those pieces together:

/**
 * Simplifies the WordPress loop.
 *
 * @param WP_Query|WP_Post[] $iterable
 *
 * @return Generator
 */
function wp_loop( $iterable = null ) {

   if ( null === $iterable ) {
      $iterable = $GLOBALS['wp_query'];
   }

   $posts = $iterable;
   if ( is_object( $iterable ) && property_exists( $iterable, 'posts' ) ) {
      $posts = $iterable->posts;
   }

   if ( ! is_array( $posts ) ) {
      throw new \InvalidArgumentException( sprintf( 'Expected an array, received %s instead', gettype( $posts ) ) );
   }

   global $post;

   // Save the global post object so we can restore it later
   $save_post = $post;

   foreach ( $posts as $post ) {
      setup_postdata( $post );
      // Do stuff here
   }
   wp_reset_postdata();

   // Restore the global post object
   $post = $save_post;

}

We’re getting there, but that pesky // Do stuff here bit is always going to be different. Let’s make one small change. We’ll remove the // Do stuff here comment and replace it with yeild $post;. This will turn our function into a generator and allow it to return the post. This allows us to use the function like this:

foreach ( wp_loop() as $post ) {
   echo '<h1>' . esc_html( get_the_title() ) . '</h1>';
}

This will loop through all the posts from the global WP_Query and output the title. This should give you a basic idea of how simple it can make the loop.

Finally

The only problem here is that the wp_reset_postdata() part of our code doesn’t run if this is a generator because the yield acts as a return and after the last post is returned the rest of the code isn’t run. However, all we need to do to fix this is to utilize a tryfinally statement, like this:

global $post;

// Save the global post object so we can restore it later
$save_post = $post;

try {

   foreach ( $posts as $post ) {
      setup_postdata( $post );
      // Do stuff here
   }
   
} finally {

   wp_reset_postdata();

   // Restore the global post object
   $post = $save_post;    
   
}

Now, anytime the generator “wraps up”, the code in the finally block will be run. This covers not only the standard use case where we are looping through all our posts, but also if we decide to break out of our loop early, like this:

foreach ( wp_loop() as $post ) {
   echo '<h1>' . esc_html( get_the_title() ) . '</h1>';
   break;
}

Super awesome!

Now the global $post object is properly set, along with a number of other important globals that setup_postdata() handles. We also don’t have to remember to reset the query when we are done, that just happens automatically! Essentially, our generator takes all the things we’d normally have to remember to do and does them for us!

Another beautiful thing about this approach is that if you mess with the $post variable in this loop, it isn’t actually the global object, so you can’t mess up global context at all!

A Better WordPress Loop

A generator allows us to extract all the things we would normally have to remember to do in the WordPress loop and put them in a function that handles them automatically… a better WordPress loop indeed!

Here is the final code (works in PHP 5.6+):

/**
 * Simplifies the WordPress loop.
 *
 * @param WP_Query|WP_Post[] $iterable
 *
 * @return Generator
 */
function wp_loop( $iterable = null ) {

   if ( null === $iterable ) {
      $iterable = $GLOBALS['wp_query'];
   }

   $posts = $iterable;
   if ( is_object( $iterable ) && property_exists( $iterable, 'posts' ) ) {
      $posts = $iterable->posts;
   }

   if ( ! is_array( $posts ) ) {
      throw new \InvalidArgumentException( sprintf( 'Expected an array, received %s instead', gettype( $posts ) ) );
   }

   global $post;

   // Save the global post object so we can restore it later
   $save_post = $post;

   try {

      foreach ( $posts as $post ) {
         setup_postdata( $post );
         yield $post;
      }

   } finally {

      wp_reset_postdata();

      // Restore the global post object
      $post = $save_post;

   }

}

Here is how you can use the generator for the global loop:

foreach ( wp_loop() as $post ) {
   echo '<h1>' . esc_html( get_the_title() ) . '</h1>';
}

Alternatively, you can also directly pass in a WP_Query object, like this:

foreach ( wp_loop( new WP_Query( 'post_type=post' ) ) as $post ) {
   echo '<h1>' . esc_html( get_the_title() ) . '</h1>';
}

Or, you can just throw some posts at it:

foreach( wp_loop( get_posts() ) as $post ) {
   echo '<h1>' . esc_html( get_the_title() ) . '</h1>';
}

You can always add additional checks if you need to:

if ( have_posts() ) {
   foreach ( wp_loop() as $post ) {
      echo '<h1>' . esc_html( get_the_title() ) . '</h1>';
   }
} else {
   echo '<h1>No posts found!</h1>';
}

Try it out on your own projects and let me know what you think!

Do you think this should be added to core?

Making WordPress REST API Calls Internally

The WordPress REST API is great for gaining access to your data from external sites or from front-end JavaScript applications. It is even great for one-off calls you probably used to make via normal WordPress AJAX. However, have you ever wanted or needed to make WordPress REST API calls internally?

What do I mean? I mean being able to make a WordPress REST API call directly within PHP without making an HTTP request. Of course, this would only work if you want the data out of the site on which your code is running.

Why?

You are probably thinking, isn’t this what WP_Query is for? Why use an internal REST API call to do something that WordPress already allows you to do? Well, the main reason is because WP_Query returns data in a completely different format than the REST API.

My particular use case for needing this was that I wanted to avoid making an initial HTTP request to fetch the initial data for a JavaScript application. While I could have the JavaScript application make an HTTP request as soon as it loaded, there were a few reasons why an internal REST API call would make more sense:

    1. I could avoid the HTTP request altogether by making an internal query and passing the initial data to the app directly from PHP. This would make my application load much faster.
    2. I could avoid the lag where a user sees the initial state of the application with no data until the initial HTTP request completes. This would make my application not only be faster but also provide a better user experience. There would be no need for initial loading graphics, time to interaction would be less, etc.
    3. In the event that users don’t actually interact with the application, no additional HTTP requests are made to the web server. If we made the extra HTTP request, we would end up loading WordPress and all the plugins twice as opposed to just once. Depending on our application’s bounce rate, this could significantly affect the load on the web server.

How to Make an Internal WordPress REST API Call

It isn’t difficult to make an internal REST API call, but it is a bit more involved than your normal WP_Query usage. Also, keep in mind that the parameters you pass to the REST API are not always the same as what you would pass to WP_Query. For example, the post_status query var would become status when making an API request.

<?php

$request = new WP_REST_Request( 'GET', '/wp/v2/posts' );
$request->set_query_params( [ 'per_page' => 12 ] );
$response = rest_do_request( $request );
$server = rest_get_server();
$data = $server->response_to_data( $response, false );
$json = wp_json_encode( $data );

Basically, you will start by creating a new instance of a WP_REST_Request. This takes two parameters: the method and the route. Since you will most likely only be querying data, you’ll probably only use the GET method for internal requests although you could make POST requests as well.

Once you have a request, you can call the set_query_params() method to pass any arguments that you would normally have set in the URL query string. You can set headers as well, but it is important to note that authentication isn’t performed when making internal requests. As such, you will want to make sure that normally protected endpoints aren’t exposed by using this method. Be sure to add any applicable capability checks.

Once you’ve set up your request object, just pass it to the rest_do_request() function to get a response object.

Finally, get an instance of the REST server by calling rest_get_server(). Then call the response_to_data() method on the server and pass it your response object. The second parameter is the embed option. If false, things like authors and featured images won’t be embedded in the data. If true, they will be embedded. What is returned by doing this is an array containing the data you would normally get in JSON format from the REST API. All you need to do to get actual JSON is to run the data returned through the wp_json_encode() function.

So what do you think? Have you done anything like this before? If so, I’d love to hear more about your use case!

Git Autocorrect

If you work with the command line often, chances are you use Git from the command line as well. How often do you find yourself mistyping a Git command only to have to type it all over again? By using Git autocorrect, we can alleviate this problem!

By default, Git will offer you one or more suggestions in the event that you type something that could be a match to an existing command. Did you know that you can have Git automatically execute a suggested command?

Here is the excerpt from the official Git documentation:

help.autocorrect
Automatically correct and execute mistyped commands after waiting for the given number of deciseconds (0.1 sec). If more than one command can be deduced from the entered text, nothing will be executed. If the value of this option is negative, the corrected command will be executed immediately. If the value is 0 – the command will be just shown but not executed. This is the default.

So basically, if you just set the autocorrect value to 1, it will automatically execute a Git command if there is only one suggestion.

Git Configuration

Run this command to set it up:

git config --global help.autocorrect 1

Credit

Thanks to Chris Davis for this tip!

My Git Aliases

Git is an awesome tool for version control and has been accepted as the industry standard. However, Git commands can be very confusing and difficult to remember. When I first learned about version control I used something called Mercurial, which had simpler and more intuitive commands (generally speaking). In an effort to tame Git and make it a bit more intuitive, I’ve created a few aliases that I think you might find helpful.

What is a Git Alias?

No, a Git alias isn’t when you commit using someone else’s name… although I’ve done that before. 😉 A Git alias is nothing more than a custom git command that can reference a longer git command or even a custom shell command. Put simply, it is a command-line shortcut.

For example, when I want to perform a git checkout, I actually just type git co because I’ve created co as an alias of checkout.

How to Create a Git Alias

So how do you go about creating an alias? The simplest way is to create one via the command line, like this:

git config --global alias.co 'checkout'

Alternatively, you can manually edit your .gitconfig file in your user directory by adding the following:

[alias]
    co = checkout

The [alias] bit shoult only be in there once, but under that you can add as many aliases as you want. All of your aliases should be indented under the [alias] heading with a single tab.

If you want to quickly start editing your .gitconfig file, just run this command:

git config --global -e

My Git Aliases

OK, on to the good stuff. Here are the aliases I use, what they do and a handy copy and paste command for adding the alias to your own .gitconfig file.

co

The co alias is a shortcut for the checkout command.

To create this alias, just run this command:

git config --global alias.co 'checkout'

ci

The ci alias is a shortcut for the commit command. I think of it as the ‘Check In’ command. While there is no checkin command in Git (or Mercurial), there is in SVN and it is the perfect opposite to the checkout command.

To create this alias, just run this command:

git config --global alias.ci 'commit'

st

The st alias is a shortcut for the status command, but with a small twist. I prefer to see the status in a condensed mode, so I add the -s flag to opt for the short display. I also add the -b flag so it always shows me the current branch. If you don’t want those flags set, just leave them off when creating your alias.

To create this alias, just run this command:

git config --global alias.st 'status -sb'

in

The in alias is patterned after the incoming command in Mercurial. Basically, it tells me if there are any incoming commits I should pull down. Ultimately, it is not so easy to git this information from Git without a lot of typing. It is also strangely satisfying to type git in.

To create this alias, just run this command:

git config --global alias.in '!git fetch && git log --oneline --graph [email protected]{u}'

Note: The ! character at the beginning of a Git alias basically causes the alias to run a shell command. As such, we can really run any command supported by our operating system. In this case, I’m just running two git commands back to back.

out

The out alias is patterned after the outgoing command in Mercurial. Basically, it tells me if there are any outgoing commits that I should push up. Again, it is also just fun to type git out!

To create this alias, just run this command:

git config --global alias.out 'log --oneline --graph @{u}..'

ready

The ready alias is one for which I have to credit my brother David. Basically, it stages all changes and then shows the current status. This is typically what you might do right before a commit, so it is aptly named. This one is also just fun to type!

To create this alias, just run this command:

git config --global alias.ready '!git add --all && git status -sb'

Note: I’ve applied my personal preferences to the status command by adding the -s and -b flags here. Feel free to customize and make it your own!

unstage

The unstage alias will do exactly what you think it does: Unstage any staged changes. While the Git way of doing this isn’t hard, it also isn’t intuitive. I always opt for intuitive where possible.

To create this alias, just run this command:

git config --global alias.unstage 'reset --'

rollback

The rollback alias will undo the last commit. It is patterned after the rollback command from Mercurial. When I first started working with Git, I found myself looking up how to do this all the time. Since Git doesn’t have a rollback command, we can add it ourselves!

To create this alias, just run this command:

git config --global alias.rollback 'reset HEAD~'

forget

The forget alias will make Git forget about one or more files. Again, this is something I used to look up all the time because it isn’t intuitive to do in Git.

This alias isn’t a meant to be used without additional parameters. For example, I wouldn’t just run git forget because it wouldn’t really do anything. However, if I want Git to forget about my huge.log file, I would just run git forget huge.log.

To create this alias, just run this command:

git config --global alias.forget 'rm --cached'

leaderboard

The leaderboard alias is just for fun and credit for this one goes to Kolbe. Basically, it just lists all the authors who have made commits in order by the number of commits they’ve made to the repository. While the number of commits isn’t the best way to judge contributions to a code base, it is a good way to get a feel for activity.

To create this alias, just run this command:

git config --global alias.leaderboard 'shortlog -s -n'

alias

Last but not least, the alias alias is used to list all your aliases! I know that when you have a bunch of aliases it is likely that you will forget about them from time to time. Maybe you need to do something more complicated and know you have an alias to do that, but don’t remember the name of it. Have no fear! Just add this alias and all you need to do to list out your aliases is type git alias!

To create this alias, just run this command:

git config --global alias.alias 'config --get-regexp alias'

Summary

So there you have it, 11 awesome Git aliases you can start using today! If you don’t want to add them all one at a time from the command line, you can just copy and paste this whole block into your .gitconfig file:

[alias]
 st = status -sb
 co = checkout
 ci = commit
 in = !git fetch && git log --oneline --graph [email protected]{u}
 out = log --oneline --graph @{u}..
 ready = !git add --all && git status -sb
 unstage = reset --
 rollback = reset HEAD~
 forget = rm --cached
 leaderboard = shortlog -s -n
 alias = config --get-regexp alias

Have you already been using Git aliases? If so, let me and everyone else know by sharing the ones that have helped you the most!

Async or Defer JavaScript Files in WordPress

There are a lot of articles out there about how to async or defer scripts in WordPress, but they assume you’ll be writing all the code or using one of the bloated plugins to make it happen.

In my case, I just needed the ability to async or defer a few scripts in a custom plugin or theme. Sure, I could add all the filters every time to make that work, but I’m a programmer. Why should I have to constantly write the same code over and over again? Why not create a simple module to handle this for me and allow me to async and defer scripts in a truly WordPress way? So I did just that.

Introducing the WordPress Async/Defer Scripts Module

A Composer library for asynchronously loading or deferring scripts in WordPress. View on GitHub or Packagist.

Requirements

  • PHP 5.3+
  • WordPress 4.2+

Installation

Add the module to your code base via Composer:

composer require wpscholar/wp-async-defer-scripts

Be sure to require the Composer autoloader in your project:

<?php

require __DIR__ . '/vendor/autoload.php';

Usage

Asynchronously load a script using the wp_scripts()->add_data() method:

<?php

add_action( 'wp_enqueue_scripts', function() {
    wp_enqueue_script( 'recaptcha', 'https://www.google.com/recaptcha/api.js' );
    wp_scripts()->add_data( 'recaptcha', 'async', true );
} );

Defer loading of a script using the wp_scripts()->add_data() method:

<?php

add_action( 'wp_enqueue_scripts', function() {
    wp_enqueue_script( 'recaptcha', 'https://www.google.com/recaptcha/api.js' );
    wp_scripts()->add_data( 'recaptcha', 'defer', true );
} );

Initialization

In most cases, you can simply follow the installation instructions and things will just work. However, if you are including this library outside of a WordPress plugin or theme, you may have to manually initialize the class:

<?php

wpscholar\WordPress\AsyncDeferScripts::initialize();

Conclusion

I’d love to see simple async and defer functionality added to WordPress core, but in the meantime, this has worked out quite well for my own personal projects and I thought I’d share it with you. What do you think?

WordPress Post Expiration Module

WordPress plugins are great, but sometimes you want to avoid having additional settings screens or giving a client access to make changes that could break functionality on their website.

If you aren’t a coder and you want to automatically expire a post in WordPress, I’d recommend that you check out the Post Expirator plugin. However, if you want a nice and simple way to expire posts without having to deal with extra admin configuration, then you should check out my WordPress Post Expiration module.

Composer Installation

All the Composer users out there can just run

composer require wpscholar/wp-post-expiration

to add the module to your WordPress project.

If added to a WordPress theme or plugin, the only code you will need to add is a line of code for each post type that should support expiration:

add_post_type_support('post', 'expiration');

You can also just add ‘expiration’ to the ‘supports’ array when defining a custom post type.

Viola!

You now have a meta box on all posts that allow you to set an expiration date and time. If no date is set, then the post will live on forever. Otherwise, it will use the WordPress cron functionality to run a task every hour and automatically trash any posts that have an expiration date in the past.

Manual Installation

Not using Composer? Just download the module into your project, require the PostExpiration.php file. Then, add this line of code:

add_action( 'init', [ '\wpscholar\WordPress\PostExpiration', 'initialize' ], 1000 );

Be sure to add the ‘expiration’ post type support to the desired post types and you are good to go!

View wpscholar/wp-post-expiration on Packagist.