My Vim experiment

For the last couple of weeks – I lost track honestly – I have been using Vim as my editor. I do this when I’m not working. I don’t want it get in the way. So, I’ve spent quite a bit of time reading the docs. Like reading as much of the docs as I possibly can without going insane.

It’s been really neat to see and learn about how much can actually be done within Vim. There are, of course, some limits to what can be done – then again that’s pretty true for just about any text editor.

The thing to keep in mind is that I really don’t have a lot of experience with many text editors. Over the years I have looked at, and used, NotePad++, Atom, Sublime Text, Coda, Brackets, and dare I say DreamWeaver. For a long time I did consider trying to use GoLive but never got a chance to really see how that all worked. I did try PHPStorm but never did fully get behind using it since I had to really think about having to learn new keyboard shortcuts

Yeah, I am not a fan of that.

That is only because I am a bit of a creature of habit when it comes to my development experience. It sounds strange to say that. Okay, writing it out but you get the idea.

I’ve come to like editing files on Vim because it makes me think a little different when it comes to editing and typing. It’s not always standard, control and z, control this or that, or any random combination of clacking that some of us are used to.One thing that did get my attention was actually repeating things. For example, if I add seven spaces to a line, typically I would select, copy then paste and keep pasting until I wanted. In vim I can type out far less because using the.makes it so much faster to repeat the last action.

I’m sure there are a lot of other things I still haven’t learned but I’m looking forward to reading and doing many of them. I mean I did manage to get NerdTree working on my first try so that has to say something right?

Weekend updates

I know it has been quite some time since I posted anything on here and I'm hoping to change that. The last time I posted anything was back in June and that was rather short lived as well. With Gutenberg getting frequent updates this could be a fun little thing and experiment for my weekends.

I say that only because the editor itself does have a lot of potential behind it but needs to get a little more steam from others. What I will be doing is posting an update every Sunday on how not only my week went but what I hope to accomplish for the week.

There have been several changes to my life and the biggest one is I am now working at Elegant Themes as a Junior Developer. The even more amazing thing is I'll be working, tinkering, and learning more about ReactJS since that is what the visual builder uses.

The biggest thing I am looking forward to is setting mini-goals for myself and hopefully helping in making the Gutenberg experience much better.

The biggest challenge could actually be keeping the posts to development related things.

A metabox for your layout options

It’s no surprise I can be vocal when I am reviewing a theme. Many know that I’ll spurt out what I end up seeing in a lot of themes. There is one thing that really does drive me crazy though and that is when people copy and paste code to their theme without actually knowing how the code actually works.

One file that has really been rather popular is using a metabox in order to choose the layout of the post or page. That’s great. I love that ability but then again who doesn’t love having that control? I think what drives me bonkers is that this code is super predictable before the file is opened. The file adds two actions. One to add_meta_boxes and the second to the save_post hooks. Great! Very super simplistic and hard to mess up, right?

I created a gist with the name of the theme changed. The code is the same that I’ve seen in many other themes though. From authors who have several themes in the repo to new authors to the repo.

One of the first things that you may notice is the use of two globals.

global $post, $deargodwhy_sidebar_layout;

First there should be no reason for that and second those hooks pass the $post object. We’ll look at the first one: add_meta_boxes

Using the developer resources as a guide we see that the hook for adding metaboxes uses two arguments. The post type and the post.

do_action( 'add_meta_boxes', string $post_type, WP_Post $post )

The first one being the string of the current post type and the second being the WordPress post object. Now, what’s super cool about that is that we can now register a metabox in any post type we want and it does on every post type if we don’t pay attention to what we are doing. There is also one more hook we could potentially use in order to use a metabox in only one specified post type. That hook is add_meta_boxes_{$post_type} and the developer docs does explain it a little better. For example, if you wanted to add a metabox to only your EDD downloads, you could do something like:

add_action( 'add_meta_boxes_download', 'jmc_download_extra_metaboxes', 10 );
function jmc_download_extra_metaboxes( $post ) {
	// Do our magic here.
}

In order to now add our metabox we do need to use the function add_meta_box() so let’s take a look at how that function is used.

add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null )

Now, if you want to take a closer look at what each one of those parameters actually does then I suggest you take a look over the developer docs. It is well worth your time if you really want to understand how to create a better user experience and understand how WordPress creates those.

Another thing I wanted to look over was the save_post callback being used. The biggest issue is the use of the foreach() loop.

foreach( $deargodwhy_sidebar_layout as $field ){  
        //Execute this saving function
        $old = get_post_meta( $post_id, 'deargodwhy_sidebar_layout', true ); 
        $new = sanitize_text_field( $_POST['deargodwhy_sidebar_layout'] );
        if ( $new && $new != $old ) {  
            update_post_meta($post_id, 'deargodwhy_sidebar_layout', $new );  
        } elseif ('' == $new && $old ) {  
            delete_post_meta( $post_id,'deargodwhy_sidebar_layout',  $old );  
        } 
     }

The reason is it is creating an unnecessary loop. The only thing that needs to be checked is the value being input and to make sure that it is a valid option. A quick change to the code and we have:

if ( ! empty( $_POST['deargodwhy_sidebar_layout'] )
	&& in_array( $_POST['deargodwhy_sidebar_layout'], array( 'right-sidebar', 'no-sidebar' ), true )
	) {
	update_post_meta( $post_id, 'deargodwhy_sidebar_layout', $_POST['deargodwhy_sidebar_layout'] );
}

Knowing those things we could make changes to the file and not only will we have a better understanding of how WordPress creates metaboxes but we have a file that doesn’t pollute the $GLOBALS with info that we only use in one place. If you look at what those changes were in the diff, you will see that not a lot was changed. It only looks that way since I removed a lot of the linting errors.

My tour of creating a PHPCodeSniffer Standard

It’s no surprise I like to learn new things. I also like to read things when I can. Okay, a lot of the time I skim through things but I make an effort to learn from it.

The last couple of weeks I’ve looked at working with the PHPCodeSniffer. I installed it and never really played with it. Not until last week did I realize my version was out of date. Easy fix but something to keep in mind. The current version at the time of this writing is 2.7.1 and that’s what I am currently running on my Windows machine as well as my MBP.

So, here are some of the things I learned from attempting to create a standard and a sniff.

Lessons Learned

  • Read the docs
  • Carefully read the docs
  • Experiment

One of the first things to understand is that you need to know where your PHPCS standards reside.  There you will see a series of folders and files. The one that we will focus on is the Standards folder. This is where our newly created Standards will live.

The steps

We will outline the steps needed to create both a standard as well as a sniff. They are:

  1. Create the directories
  2. Create the XML file
  3. Create the sniff or sniffs if you want more

Sounds super simple right?

So let’s move on!

The first thing we will do is create the directories. The first one is the name of our standard. The second directory will be Sniffs and this is where all of our sniffs will reside. For example, WordPress standards looks like the following image:

Inside of the folder we will then create the ruleset.xml file with the needed information for our standard. It will look something like the following image:

Now, we can finally create our sniffs. But wait there is one thing you should know before making this and that is that you need to have a category folder.

Why?

It makes it easier to organize and know what we are looking for as well. For the sake of this post, I created an Example folder and inside of that I created a ListSniff.php file. Pay close attention to that detail as it will matter down the line. I learned this one because of errors I kept getting.

So, our new folder structure should look a little like:

codesniffer\standards\
codesniffer\standards\YourStandard
codesniffer\standards\YourStandard\ruleset.xml
codesniffer\standards\YourStandard\Sniffs
codesniffer\standards\YourStandard\Sniffs\Example
codesniffer\standards\YourStandard\Sniffs\Example\ListSniff.php

Now we can create our sniff!

This is where the fun really begins for some.

The important thing here is both the file and the class inside of the file must end with Sniff. For my example I named it ListSniff.php so the class would look like:

<?php
/** Example class created for demonstration purposes only **/
class YourStandard_Sniffs_Example_ListSniff implements PHP_CodeSniffer_Sniff {

	public function register() {
		return array();
	} // end register()

	public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) {

		// Tokenize the file, right?
		$tokens = $phpcsFile->getTokens();

		// We need this in order show what the error actually is.
		$phpcsFile->addError( $error, $stackPtr, $code = '', $data = array(), $severity = 0, $fixable = false );

		// We can even add a warning if we want.
		$phpcsFile->addWarning( $warning, $stackPtr, $code = '', $data = array(), $severity = 0, $fixable = false );
	} //end process()
}

You will see two very interesting things here. The first one being the naming of the class. It needs to be:

class {Folder of the standard name}_{the Sniffs folder}_{subfolder of Sniffs}_{your sniff}Sniff

And the second being the implements PHP_CodeSniffer_Sniff. This is straight from their documentation:

Each sniff must implement the PHP_CodeSniffer_Sniff interface so that PHP_CodeSniffer knows that it should instantiate the sniff once it’s invoked.

The reason is because the PHP_CodeSniffer_Sniff interface has two methods that need to be utilized. The register() and process() methods.

The methods

The first one – register – simply does that. You register what tokens you want the CodeSniffer to catch. PHP.net does provide a super handy list with all the available tokens.

Now, let us take a look at how the addError and addWarning sort of work so you can get an idea of what you can do.

First the addError:

/**
@param string  $error    The error message.
@param int     $line     The line on which the error occurred.
@param int     $column   The column at which the error occurred.
@param string  $code     A violation code unique to the sniff message.
@param array   $data     Replacements for the error message.
@param int     $severity The severity level for this error. A value of 0
                         will be converted into the default severity level.
@param boolean $fixable  Can the error be fixed by the sniff?
*/

What’s really nice is that the addWarning does nearly the same:

/**
@param string  $warning  The error message.
@param int     $line     The line on which the warning occurred.
@param int     $column   The column at which the warning occurred.
@param string  $code     A violation code unique to the sniff message.
@param array   $data     Replacements for the warning message.
@param int     $severity The severity level for this warning. A value of 0
                         will be converted into the default severity level.
@param boolean $fixable  Can the warning be fixed by the sniff?
*/

With that I created a random test sniff. It turned out a little like:

class Examplee_Sniffs_Example_FunctionSniff implements PHP_CodeSniffer_Sniff {

	public function register() {
		return array( T_FUNCTION );
	} // end register()

	public function process( PHP_CodeSniffer_File $phpcsFile, $stackPtr ) {

		// Tokenize it!
		$tokens = $phpcsFile->getTokens();

		// We want to check.
		if ( $tokens[ $stackPtr ]['content'] ) {

			// build up our message to show on the report.
			$warn = 'Make sure %s is prefixed';

			// build up the array of data we want to pass
			$data = array( trim( $phpcsFile->getDeclarationName( $stackPtr ) ) );

			// finally we add our warning. Could use addError().
			$phpcsFile->addWarning( $warn, $stackPtr, 'found', $data );
		}
	} //end process()
}

I did try it out on Twenty Seventeen functions file and got the following:

FOUND 0 ERRORS AND 14 WARNINGS AFFECTING 14 LINES
----------------------------------------------------------------------
  27 | WARNING | Make sure twentyseventeen_setup is prefixed
 200 | WARNING | Make sure twentyseventeen_content_width is prefixed
 222 | WARNING | Make sure twentyseventeen_fonts_url is prefixed
 257 | WARNING | Make sure twentyseventeen_resource_hints is prefixed
 274 | WARNING | Make sure twentyseventeen_widgets_init is prefixed
 315 | WARNING | Make sure twentyseventeen_excerpt_more is prefixed
 336 | WARNING | Make sure twentyseventeen_javascript_detection is
     |         | prefixed
 344 | WARNING | Make sure twentyseventeen_pingback_header is
     |         | prefixed
 354 | WARNING | Make sure twentyseventeen_colors_css_wrap is
     |         | prefixed
 371 | WARNING | Make sure twentyseventeen_scripts is prefixed
 433 | WARNING | Make sure twentyseventeen_content_image_sizes_attr
     |         | is prefixed
 460 | WARNING | Make sure twentyseventeen_header_image_tag is
     |         | prefixed
 479 | WARNING | Make sure twentyseventeen_post_thumbnail_sizes_attr
     |         | is prefixed
 499 | WARNING | Make sure twentyseventeen_front_page_template is
     |         | prefixed
----------------------------------------------------------------------

So you can see some versatility when using the PHPCodeSniffer. If you really want to help out the Theme Review team then I highly recommend heading over to the github repo and helping out.

As for me, I’ll be digging more into how to create random tests because I like dabbling and breaking those things.

WordPress and MediaElement styles

Okay, this is more of an experiment I was running because I was reached out by a friend about a theme question.

This actually got me thinking about the shortcodes. The audio and video ones in particular. The reason is that when you use the [audio] shortcode WordPress will use MediaElementJS and enqueue both the JavaScript file and the CSS stylesheet.

Turns our there is a filter for those! Well, two really. One for each one. I wanted to dig deep for this one because styling the player is something I have wanted to do for a long time. Today I found out I can!

Yes, I am excited about it.

Yes, I am writing about it.

Yes, I will share what I found with you.

The steps

This took me about a day’s worth of effort only because I didn’t really know what I was looking for. I knew I needed to figure out what styles were being used and where. By default WordPress registers a few scripts and styles for MediaElements. The styles are registered in the script-loader file. There are two that are registered. The second one –wp-mediaelement– depends on the first registered one so really it is loading two files when either shortcode is used.

Now, how did I find this out?

I looked up wp-mediaelement in the project and found 16 results. The first place I looked was the ajax-actions file only because it was the first result and I wanted to see how it was done as well. Looked at the file and noticed that it uses wpview_media_sandbox_styles() to get the stylesheet URLs but not exactly what I was looking for. Though it is a neat little function.

Next up was the media.php file. This was the one I really should have been looking in. 6 results and one was from the wpview_media_sandbox_styles function so I was making some progress I guess. In the first result it was inside of the wp_playlist_scripts() function and it enqueues the style and a playlist script. Not exactly what I need but getting close.

The second result landed me where I needed to be. A nice filter. The wp_audio_shortcode_library to be precise. What’s really nice is the video is much like it as well. It is wp_video_shortcode_library and they work the same way.

The Filters

apply_filters( 'wp_audio_shortcode_library', 'mediaelement' );
apply_filters( 'wp_video_shortcode_library', 'mediaelement' );

Pretty cool, right? So then how would it be used?

In the functions.php of your theme you could potentially do something like:

add_filter( 'wp_audio_shortcode_library', 'jmc_new_lib' );
add_filter( 'wp_video_shortcode_library', 'jmc_new_lib' );
function jmc_new_lib(){
	// Because we still want the script to load but not the styles
	wp_enqueue_script( 'wp-mediaelement' );
	wp_script_add_data( 'wp-mediaelement', 'conditional', 'lt IE 9' );

	// Enqueue our own styles here.
	wp_enqueue_style( 'jmc-media-styles', get_template_directory_uri() . '/css/media.css' );

	return '';
}

Super sweet if you ask me. That’s great and all but what about the markup? Now we have to think about what needs to be styled right?

Well, I’ve gone ahead and extracted some of the classes for both the audio and video markup to make it easier:

.mejs-offscreen {}
.mejs-container {}
.svg {}
.wp-audio-shortcode {}
.mejs-audio {}
.mejs-inner {}
.mejs-mediaelement {}
.mejs-layers {}
.mejs-poster {}
.mejs-layer {}
.mejs-controls {}
.mejs-button {}
.mejs-playpause-button {}
.mejs-play {}
.mejs-time {}
.mejs-currenttime-container {}
.mejs-currenttime {}
.mejs-time-rail {}
.mejs-time-total {}
.mejs-time-slider {}
.mejs-time-buffering {}
.mejs-time-loaded {}
.mejs-time-current {}
.mejs-time-handle {}
.mejs-time-float {}
.mejs-time-float-current {}
.mejs-time-float-corner {}
.mejs-duration-container {}
.mejs-duration {}
.mejs-volume-button {}
.mejs-mute {}
.mejs-horizontal-volume-slider {}
.mejs-horizontal-volume-total {}
.mejs-horizontal-volume-current {}
.mejs-horizontal-volume-handle {}
.mejs-clear {}
.wp-video {}
.wp-video-shortcode {}
.mejs-video {}
.mejs-overlay {}
.mejs-overlay-loading {}
.mejs-overlay-error {}
.mejs-overlay-play {}
.mejs-overlay-button {}
.mejs-volume-slider {}
.mejs-volume-total {}
.mejs-volume-current {}
.mejs-volume-handle {}
.mejs-fullscreen-button {}

Those are some of the common classes that are used in the final markup. It may not be a complete list but it is a starting point for many and I hope it does help somebody out in theming the audio and video post formats. I will mention this because I know it may be asked down the road: some of those classes may have inline styles so it would be w

I also created a quick gist for the files if you only wanted to target one media type. This is useful if the user has a playlist.

In the following example, I’ve removed the core action and am only documenting the basics.

// remove the scripts/styles originally enqueued
remove_action( 'wp_playlist_scripts', 'wp_playlist_scripts' );

// enqueue ours instead
add_action( 'wp_playlist_scripts', 'jmc_new_liststyles', 10, 2 );
function jmc_new_liststyles( $type, $style ) {
	// $type is the type of playlist either an 'audio' or 'video'.
	// $style can be core 'light' or 'dark' but can add more by having user input
	// and enqueueing the needed style.
	wp_enqueue_style( 'jmc-style', 'path/to/file' );

	// Because we still want to enqueue the script just not the style.
	wp_enqueue_script( 'wp-playlist' );
}

What’s cool about that is that you really can add your own styles if you want. I know there are some themes that take advantage of “skins” or color schemes and could really benefit from this. I may just try and do this on one of my days off or when I can. In the meantime I hope this helps some plugin authors and even more theme authors with styling and using core methods rather than relying on using wp_deregister_style() for this.

Video: WordPress template hierarchy

Earlier today I had some time to make a quick video. I have written about the template hierarchy before and I’m sure there are tons of other resources available out there. This justs adds to that ever-growing-list. The reason it drives me crazy is because of that front-page.php file that I see every so often or when I see a theme that uses the Template Name: Front Page in order to create that static front page.

The thing is that the front-page template is meant to be used once. On the FRONT PAGE. Why would you want that page to be in other pages? This is what irritates me most about that.

Anyway, enjoy, don’t, up to you. As for me I’m heading out to get some sculpting tools.