Presenting WordPress content with themes

There are a lot of ways of getting user content in WordPress. Plugins are ideal for creating that content and provide that functionality. Themes are better at presenting that content.

One of the many things we often see in theme reviews is what are known as pseudo post types. I love Justin’s post in regards to content and post types so do give a read to understand a little more. The following paragraphs will focus more on code and methods of not only getting content from the WordPress database but also on how to make use of that data for use in the customizer and on the front-end of a site.

The content

First we need to think about what we want to show on the page, right? For this example will focus on a single post. What’s super cool is that this can be applied to custom post types as well and not just the standard post. The function we will use for this is get_post_meta() and the developer documentation is a good starting point: https://developer.wordpress.org/reference/functions/get_post_meta/

What matters here is the returning value from that function:

(mixed) Will be an array if $single is false. Will be value of meta data field if $single is true.

That’s great, but what does it mean, right? Let’s say what we add a custom field to a post. Perhaps a subtitle. Depending on what you set your custom field to, you would use:

if ( $subtitle = get_post_meta( get_the_ID(), 'subtitle', true ) ) {
	printf( '<span class="subtitle">%s</span>', $subtitle );
}

That’s much easier than creating a custom meta box that would be lost when the theme is changed, right? I know you may be asking, but what about other post types? Well, we can use get_metadata() for that. The developer docs help here as well. All we do is change a small thing and we can use it in an archive style.

if ( $subtitle = get_metadata( get_post_type(), get_the_ID(), 'subtitle', true ) ) {
	printf( '<span class="subtitle">%s</span>', $subtitle );
}

Great!

Other types

So, with that you have a basic starting point of core’s built-in capabilities. Metadata is super useful and easy to get. Best part is that if that value doesn’t exist, we don’t output anything! No extra markup or code to worry about.

Now, there are tons of plugins out there that create all sorts of data and content for users. Let’s take a quick look at one that is pretty popular: testimonials.

What’s super cool is that by using a few function_exists() we can check if a plugin is active or not. The registration method may differ from plugin to plugin but the basic thing is to use the right function to check. There are a few functions we can use:

  • function_exists()
  • method_exists()
  • class_exists()
  • interface_exists()

That’s super cool and even core has one that can be useful as well:

  • post_type_exists()

Phenomenal if you want to check for a testimonial post type, or a portfolio, or a form, event, you name it. For this example I’ll use the Easy Testimonials plugin to test.

if ( class_exists( 'easyTestimonials' ) && post_type_exists( 'testimonial' ) ) {
	$testimonials = new WP_Query( array( 'post_type' => 'testimonial', 'posts_per_page' => 3 ) );
	if ( $testimonials->have_posts() ) {
		while ( $testimonials->have_posts() ) {
			$testimonials->the_post();
			the_title( '<h3 class="testimonial-title">', '</h3>' );
		}
	}
	wp_reset_postdata();
}

Super quick example. You can see what it is doing at the beginning. We are checking to see if the class easyTestimonials exists as well as the post type. If the functions return true then we can run our query. What’s nice is that now we are in control of how to present that content however we desire.

But what about the customizer?

I mentioned this a little earlier and we can use this as callback for a control. Yes, conditionally show a control based on what is active and available. Super awesome, right?

In this example we will use the custom fields suite plugin for a page customizer control. This is going to be a unique example in that we are going to check if the plugin is active and if a field is populated on a page. Now, it may not be the best example but it will give you an idea of how it works.

add_action( 'customize_register', function( $wp_customize ) {
	$wp_customize->add_setting( 'hero-location',
		array(
			'default' => 'above',
			'sanitize_callback' => 'jmc_sani_location'
		) );
	$wp_customize->add_control( 'hero-location-control',
		array(
			'settings'        => 'hero-location',
			'label'           => __( 'Hero Image Location', 'text-domain' ),
			'description'     => __( 'Where will the hero image show? Above or below the secondary menu location', 'text-domain'),
			'section'         => 'layout',
			'type'            => 'select',
			'active_callback' => 'jmc_check_field',
			'choices' => array(
				'above' => __( 'Above', 'text-domain' ),
				'below' => __( 'Below', 'text-domain' )
			)
		) );
}, 10 );
function jmc_check_field(){
	// bail if it's not a page
	if ( !is_page() ) {
		return false;
	}

	// check for the function and value
	if ( function_exists( 'CFS' ) && CFS()->get( 'hero-image' ) ) {
		return true;
	}

	// if nothing we won't show the control
	return false;
}

Let’s break it down a little bit. The part that really matters is:

'active_callback' => 'jmc_check_field'

This callback is what will handle our logic. This ultimately determines if that control will show or not. We want to begin with the assumption that it will not show so we always return false at the end. What’s super cool is that this can be done with sections as well. This next example is nice because we check for the available post types and can use a new WP_Query on the theme to get the content.

add_action( 'customize_register', 'jmc_customize' );
function jmc_customize( $wp_customize ) {
	// get list of post types
	$post_types = get_post_types( array( 'public' => true, '_builtin' => false ), 'object' );

	if ( ! empty( $post_types ) ) {
		$types = array();
		foreach( $post_types as $type ) {
			$types[$type->name] = $type->label;
		}

		$wp_customize->add_section( 'section-one',
			array(
				'title'           => __( 'Front Page sections', 'text-domain' ),
				'description'     => __( 'Choose what else shows on the front', 'text-domain' ),
				'active_callback' => 'jmc_haz_post_types'
			) );

		$wp_customize->add_setting( 'section-one-type',
			array(
				'default'           => '',
				'sanitize_callback' => 'jmc_post_validate',
				)
		);

		$wp_customize->add_control( 'section-one-control',
			array(
				'label'       => __( 'The post type for section one', 'text-domain' ),
				'description' => __( 'Choose what post type you would like to show', 'text-domain' ),
				'settings'    => 'section-one-type',
				'type'        => 'select',
				'choices'     => $types,
				'section'     => 'section-one'
			)
		);
	}
}

function jmc_haz_post_types() {
	$types = get_post_types( array( 'public' => true, '_builtin' => false ), 'object' )
	return empty( $types );
}

function jmc_post_validate( $value, $setting ){
	$post_types = get_post_types( array( 'public' => true, '_builtin' => false ), 'object' );
	if ( array_key_exists( $value, $post_types ) ){
		return $value;
	} else {
		return $setting->default;
	}
}

Then on the front-end we could do something like:

if ( ! get_theme_mod( 'section-one-type' ) === false ) {
	$type = new WP_Query(
	array( 'post_type' => get_theme_mod( 'section-one-type' ),
		'posts_per_page' => 3
		)
	);

	if ( $type->have_posts() ):
		while( $type->have_posts() ): $type->the_post();
		the_title( '<h3>', '</h3>' );
		endwhile;
	endif;
	wp_reset_postdata();
}

The thing to remember is that content should remain when the theme is switched. There should be no reason for a user to have to input the same thing over and over again on every theme switch – after all they are after the design and not the content of the theme. A good practice to keep in mind when creating your options is:

Do I give them decision A or decision B?

A new theme and a bit of a rant

I switched out my theme to the Poseidon theme by ThemeZee. I wanted to try something new and looked around at some of the recent themes available on the free repo. In my personal opinion there are very few themes that are well designed. There are several reasons for that and of course many of those being my own.

At times when I see the repo submissions I wonder why they are doing it? There are a few that want to learn about the process, a few that want the exposure, and quite a few that want to promote. I’m not against it but I do feel that there is a time and place for that. I’ve said it again and I’ll say it again. I love what I do. I’d do it for free – if I really could.

I had to think back to when I was actually reviewing themes and posted a comment on a ticket. I had to search for it because I couldn’t remember what theme ticket I had posted it to.

I made an analogy within the ticket:

You don’t just go to Carnegie Hall and begin to play, you learn about how to play, scales, harmonics, rhythm, tone. The basics. Much like a theme, you have to learn how to build one. You can’t just copy/paste code all willy-nilly in hopes that it will pass. That’s not how you as a theme author learn, that’s not fair to the user, it’s not fair to the theme reviewer, it’s not fair to you. There should be no reason a theme author doesn’t know their code.

What I dislike is seeing a theme author not applying themselves to learning. There are a lot of things to be learned. Security, escaping, translation, actions, filters. These are things that themes are capable of doing and should be doing. You can make a theme that is capable of being extended, filtered, modified with just a few lines of codes. It just takes time to learn these things.

Those last sentences still ring true with many theme authors that are submitting their themes. That’s just the code.

I’m not even going to get into the design aspect of it. Main reason is because there are so many copycat designs being submitted. That and the ones that could be decent are ported/migrated from static HTML pre-built design. I know there are a few out there who would agree that we need more niche themes in the repo, and I wholeheartedly agree with that.

Yes, I do at times still feel that way about some of the tickets I come across, be it the ones I review or the ones I read when I look through the list of submissions. Many have some good ideas but terrible design, and others are terrible ideas with great design.

Yes, reviewers can make suggestions but they are merely that. Authors should also be open to the ideas reviewers provide rather than just put them off.

At this point I already feel like I’m beginning to trail off into other topics so I’ll end it with one last thing. Learning about the elements of design are a good starting point for creating a good looking theme. There are a lot of places to takes queues from. One I often like is A List Apart.

The quarrel for theme content

If you follow the theme review you know what I’m talking about. If you don’t let me give you brief glimpse of what I am going to talk about.

For as long as I can remember being in the review team, there has been an issue of themes not being allowed to do certain things. One of which is “creating content.”

If you know how WordPress themes work, that’s awesome! If you don’t let me try to explain a little bit with a simile. A WordPress site is very much like a car. It has an engine, a rear-view mirror, a body, some seats, and some wheels. Many of those can be replaced, switched, altered and tailored to suit your needs. If you wanted to go off-roading you get a different suspension, different tires maybe a radio just in case. Now, where do themes fit in this?

Themes can be like the paint or color. It makes it so you can stand out, be seen or blend in, depending on what you want. The paint doesn’t add an extra mirror, an extra wheel, or bells or whistles. It showcases your car. Simply that.

That’s the short story of it.

A look way back

In order to look forward we also have to look back. I’m talking way back to when the review team was first created. I wasn’t around the community but I am sure there are some that will remember this and smile:

The review process is intended to catch technical issues and ensure that new themes conform to modern web standards and WordPress standards. Theme reviewers may also provide some feedback on aesthetics, but users of the theme gallery will have an opportunity to provide feedback on the design after the theme is available in the gallery.

That is a quote from the Theme Review codex page from June 11, 2010. Yes, I did say way back. A few months pass and the page does start to get more and more informational to not only reviewers but authors as well. The process is outlined, the scope of the process, how to become a reviewer, and some general guidelines in theme development are beginning to take place. Awesome!

In August 2010, the Theme Unit Tests are added. This is a very pivotal and important part and I cannot emphasize this enough. There is a reason for this and I’ll talk about that a little later.

For now, let’s keep going down memory lane.

Let us jump to May 27, 2015. A post on the WP Tavern got quite a few comments about a guideline that had been set for several years but was now being “enforced.”  The rule in question is:

Themes are required to define the presentation of user content, and must not be used to define the generation of user content, or to define Theme-independent site options or functionality.

This was added to the codex guidelines on March 8, 2012. So, for the last four years this rule had been in place and never really defined and rarely brought up by others in the review community. At least in translation. You see the review team is made up of people from all around the world. India, England, Chicago, Canada. A lot of it can be left up to interpretation as well and that’s when things can go wrong.

The current issue

Currently we are faced with a lot of themes that add extra things to a user’s site and that makes it hard to switch to a new theme – for some. This can be something so simple as a section that has an image and some additional text. What many reviewers like to call: pseudo-post types. Even the current requirements states:

The theme options should not be pseudo custom post types and save non-trivial user data. Non-design related functionality is not allowed

Very wordy and a little hard to follow for some, right? I consider myself fairly smart when it comes to certain things but I had to read that several times to fully understand it. It makes sense when you explain it but when you try to be concise with limited words, you do lose some of the meaning.

Think of it this way. What information can the theme get, or what data is available to show and actually show it. Very much like the car’s paint or style.

Let’s say you wanted to showcase the wheels. The theme won’t replace them, it merely coats the rims in a brighter color than the body to emphasize them. The paint is not creating an extra antenna, or an extra head light. It emphasizes what the car has. And that is what a theme should really do.

The biggest take-away from the first iteration is:

Themes are required to define the presentation of user content

The content issue

Okay, I did say I was going to mention the unit test. I left this for last because it ties together the car simile. It is the interior of the car.

When creating a theme, it is the user content that is displayed. Let me say that again.

When creating a theme, it is the user content that is displayed.

The theme unit test is useful for not only reviewing a theme but creating as well. Now, I know there may be a few people who say the current demo is stale, I agree, but if you want to change it act upon it. You can’t remove a thorn from your foot by simply dismissing it. You have to actually do something about it.

There is a meta ticket that has been around for nearly the same amount of time. It was created three years ago and still not resolved. If you want to change it, join in.

If you are a theme author, I implore and challenge you to download as many dummy content files as you can get your hands on. Use that as your starting point and find a way to display it all without resorting to adding an extra text input field.

My dealing with layouts

The other day I got a chance to rewrite a bit of code. It was fun. It dealt with changing from an object to an associative array. It may sound super easy for some but for my mind it took a little bit to figure out the right way of creating a good way of filtering that out.

The issue was creating a good way to not only create a layout array with information but a decent way of a theme or plugin to filter it out. Creating some defaults was the easy part. I knew wp_parse_args would be a good solution to filling in any missing information. So I quickly began with what information was actually needed:

$defaults = apply_filters( 'jmc_layout_args', array(
	'layout_name'      => '',
	'layout_label'     => '',
	'image_src'        => '%s',
	'is_global_layout' => false,
	'is_post_layout'   => true,
);

Worked great for setting the main defaults. The next part was making sure the needed layout was filterable. Of course I had to use a foreach loop to iterate over that.

foreach ( $layouts as $id => $info ) {
	$layouts[ $id ] = wp_parse_args( $info, $defaults );
}

Cool. I managed to get the layout with some default information if nothing was passed. Well, what happens if you wanted to edit a particular layout’s data? I looked a little closer and realized I could pass one more argument to apply_filters. Yep!

foreach ( $layouts as $id => $info ) {
	$defaults = apply_filters( 'jmc_layout_args', array(
		'layout_name'      => '',
		'layout_label'     => '',
		'image_src'        => '%s',
		'is_global_layout' => false,
		'is_post_layout'   => true,
	), $id );
	$layouts[ $id ] = wp_parse_args( $info, $defaults );
}

Awesome! And with that we can now filter out not only the default arguments passed but on a layout basis if wanted by a theme or plugin.

Let’s say we have three layouts and wanted to change one. We would use something like:

add_filter( 'jmc_layout_args', function( $args, $id ) {
	if ( $id == 'three column' ) {
		return array(
		'is_global_layout' => true,
		'is_post_layout'   => false,
		);
	}
	return $args;
}, 10, 2 );

Quick, simple, and a little dirty.

In search of a notice API

Yes, I’m writing about the admin notices. I know some are already up to their ears with that and I’m on that boat. The admin area is – and should be – for the user. Any notices that appear need to be informational. Not a nag. With that being said, I know there are some that would like to promote or even encourage their users to leave a review. I’m for that but there is a time and a place.

The admin area isn’t one. Nor should it be.

I do think part of that is because there really is no proper function, or hook, for using those. [ There really should not be. ] But for the sake of experimentation I went and played around with a few things. This is what ensued:

The code

It is pretty quick and decently documented.

// because otherwise it will be a turd-nugget
add_action( 'admin_init', 'check_for_notice_dismiss' );
function check_for_notice_dismiss() {
	// we check if the setting is set, making sure that it does not return false
	if ( get_theme_mod( 'theme-notice' ) === false ) {
		// we add our action for the notice
		add_action( 'admin_notices', 'we_add_our_notice' );
		// super hackish only because there are some that aren't running 4.5 and
		// so they can't use wp_add_inline_script()
		add_action( 'admin_footer', 'our_jquery_action' );
		add_action( 'wp_ajax_our_jquery_dismiss', 'our_jquery_dismiss' );
	}
}

// callback for our admin notice
function we_add_our_notice() {
	// checking for our theme screen because we can
	if ( get_current_screen()->id !== 'themes' ){
		// get the message
		$string = __( 'How about you review our theme?', 'text-domain' );
		$html = '<div id="my-theme-notice" class="notice is-dismissible notice-info"><p>%s</p></div>';
		// the final outout of the notice
		printf( $html, $string );
	}
}

// hackish job so we don't have to enqueue an extra file
function our_jquery_action(){ ?>
<script>
jQuery( document ).on( 'click', '#my-theme-notice .notice-dismiss', function() {
	jQuery.ajax({
		url: ajaxurl,
		data: {
			action: 'our_jquery_dismiss'
		}
	})
})
</script>
<?php }

// callback function for our AJAX
function our_jquery_dismiss() {
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
		set_theme_mod( 'theme-notice', true );
	}
	die();
}

Really I only did test using a theme which does explain the use of get_theme_mod(). There is potential in creating some standard function in adding a dismissible notice.

Something along the lines of:

function wp_add_notice( $message, $dismiss = true, $type = '' ) {}

Or even as a class:

class WP_Notice {

	var dismiss = true;
	var types = array( 'info', 'error', 'updated', 'saved' );

	public function __construct( $message, $type, $dismiss ) {
		if ( !$message )
			return;
		// the rest of the code
	}

	private function render_message( $message, $classes ) {
		printf( '<div class="%s"><p>%s</p></div>', esc_attr( $classes ), esc_html( $message ) );
	}
}

I do think the class would be better suited for that but that could just be me. There you have it! Possible ideas to iterate over.

Some theme review videos

It’s been some time since I was last able to record some video on theme reviews. The last time I did it was a quick overview of my review process. Super simplistic overview of a theme review. Today I was able to record an overview of what an admin review can be.

As you can see I tend to keep a tab open to the requirement list. Part of that reason is so that I can quickly link to the section that needs to be addressed. The other video I was able to create was of a quick overview of the approved themes list. This is where themes go once the reviewer feels all things have been met so an admin can look over just in case things were missed. That video is:

Hope that helps out at least one person in how WordPress theme reviews work as well as the workflow. If you really want to learn more then read about the entire process here or even join the team.

Theme Review tips, tricks, and take aways

WordPress theme reviews are:

  • Fun
  • Entertaining
  • Demanding
  • Awesome
  • Time consuming

There are more but those are the ones that came to mind first. The last one is the one I really want to focus on the most and there is a reason for it. Recently, the review team posted a call to tips on theme reviews. I chimed in and now I feel a little more compelled to expand a little more on my personal site.

I’ve been doing reviews for quite some time and have got quite a few reviews under my belt. Currently about 2,600 that have my name attached to them. Yeah. Safe to say I’ve looked over a lot of code over the years. I have loved every single moment because I love knowing that I have helped out not only one person but an entire community by doing what I do. I am looking forward to being able to make more videos down the road to help others.

So, onward!

Tips

The biggest tip really is get your testing environment setup. My review setup is a little odd. I use Windows 7 as well as OSX 10.9.5 with VVV, Variable VVV, and the development subversion repository to test all themes. Yes, I like to live dangerously. The plugins I use are:

Active plugins

Extra plugins

As you can see I use quite a few plugins and each serve their own purpose. The extra plugins are not always active when I conduct my reviews. I only activate them when I want to try to break the theme or see if it does break.

A great tip is to always look at how core does things. Knowing how core works helps you out in knowing when a theme is creating too much content or even when it comes to explaining to an author how to better improve their theme.

Tricks

Now, the browser is Chrome and my editor of choice is Brackets. I got used to working with it and haven’t tried much else. Was never a fan of IDEs because I grew up looking at the markup in Notepad. Yes. Notepad. We all started out somewhere. I do like using the “Find in Files” feature and regular expressions to looks for certain things within the theme. I setup a few rules so it doesn’t search certain files or folders though the folder restriction is when I’m looking for core code and inline documentation.

regex-search

That’s great and all but that doesn’t really show much else. When I post a comment on the ticket and let the author know I often use one of two methods of letting them know what is still in need of fixing. The first template outlines the requirements and I bullet out what in particular needs to be addressed.

= Required =
Note all required items that theme needs to fix before theme can be approved

== a11y ==

== Code ==

== Core/Features ==

== Plugin Territory ==

== Documentation ==

== Language ==

== Options/Settings ==

== Styles/Scripts ==

= Recommend =

The second:

= Required =

=== header.php ===
* missing translation [L4,l6,L10]

=== functions.php
* plugin: `add_filter( 'show_admin_bar', '__return_false' );` please remove

= Recommend =
* The red on the navigation makes it a little hard to read some of the menu items, consider a darker shade or use a lighter text color

I have always liked using the second method because it forces me to go file by file. That is the reason it can take a long time to review a theme. Even more when some include frameworks. That’s files and folders to look over.

Take-aways

The biggest gain, of course, is that I’ve learned a lot about how WordPress works and how themes are created by many.

WordPress underscore template

The last few posts I’ve mentioned diving into creating an underscore theme. There is now one core ticket I’ve been keeping an eye on and will continue to do so until it is resolved.

Since the last post I did install the REST API plugin so this now means I am one step closer to converting this site to a project site. Yes. Expect things to break here this year. 🙂

A few links

In my quest for theming in JS I came a across few links that helped shed some light as to how WordPress does things not only within the customizer but in the admin areas. I love reading the inline docs for that reason. There are a few other tutorials and posts I came across that may also help others out there:

Great and wonderful resources. So let us write a little code!

JS code

One of the first things we want to do is enqueue our main JavaScript file and add jQuery and underscore as a dependency.

add_action( 'wp_enqueue_scripts', function(){
	wp_enqueue_style( 'default', get_stylesheet_uri() );
	
	$paged = get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;
	
	wp_enqueue_script( 'jmc-main-js', get_template_directory_uri() . '/js/main.js', array( 'jquery', 'underscore' ) );
	wp_localize_script( 'jmc-main-js', 'site', array(
		'restURL' => get_rest_url(),
		'name' => get_bloginfo( 'name', 'display' ),
	) );
});

Awesome! In the above we have enqueued our stylesheet and our main JavaScript file we will use. In our file we will use something like:

_.templateSettings = {
	evaluate:    /<#([\s\S]+?)#>/g,
	interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
	escape:      /\{\{([^\}]+?)\}\}(?!\})/g,
};

// Site name
jQuery( document ).ready( function($){
	var titletemplate = _.template( $( '#site-title' ).html() );
	$( '#masthead ' ).append( titletemplate({name: site.name }) );
});

In the JS you see we create a new variable ( titletemplate ) and it stores the markup from the site-title jQuery is getting. From there we can now use the append() method to add the newly created markup to our #masthead element. What does it look like?

<script id="site-title" type="text/template">
	<h1 class="site-name">{{{ name }}}</h1>
</script>

Fairly neat, yeah? We have now attached the site’s name via JavaScript. Yeah, not a huge deal since you can also do it with basic PHP and WordPress core functions but it is something neat to experiment with specially if you want to use some neat JavaScript/CSS effects.

That’s great but what about posts? Because we declared our templateSettings in the global space we can use the core methods of handling underscore templates. So rather than using:

  • <%= %>
  • <%- %>
  • <% %>

Why the change?

There may be a few that ask why using mustache style and not ERB that underscore uses. The reason is because in some cases PHP will be setup to use ASP style tags and we don’t want any issues to arise from that. So, rather than having to list off another dependency and another file be loaded we instead use that small snippet that makes it work. That code can be found in the wp-util file and if we look at the code we can see what it is doing:

wp.template = _.memoize(function ( id ) {
	var compiled,
		/*
		 * Underscore's default ERB-style templates are incompatible with PHP
		 * when asp_tags is enabled, so WordPress uses Mustache-inspired templating syntax.
		 *
		 * @see trac ticket #22344.
		 */
		options = {
			evaluate:    /<#([\s\S]+?)#>/g,
			interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
			escape:      /\{\{([^\}]+?)\}\}(?!\})/g,
			variable:    'data'
		};

	return function ( data ) {
		compiled = compiled || _.template( $( '#tmpl-' + id ).html(), null, options );
		return compiled( data );
	};
});

It is simply passing an object with a few options. And with that we can now use:

  • {{ name }} for escaped data
  • {{{ name }}} for un-escaped data
  • <# _.each() #> to evaluate the code

So now if we had to iterate over an array of posts we can use underscore’s each() method to do so. It could look something like:

<script id="post-tpl" type="text/template">
<# _.each( posts, function( post ){ #>
	<article class="post" id="{{ post.id }}">
		<h2 class="post-title">{{{ post.title.rendered }}}</h2>
	</article>
<# }) #>
</script>

Great!

I will end it by noting that I am not using the tmpl- prefix because I am using underscore’s template() method and passing it our template directly. One advantage, I guess. So, go. Explore, break things, and learn from it!

A few core changes

In the last post I mentioned I wanted to dive a little bit into using Backbone and Underscore for a theme. I still am pursuing that. I’ve made some progress on that front so that’s a good thing.

There is one thing that does need to change a little bit. The libraries used in core. Currently they are at version 1.2.3 and 1.8.3 for Backbone and Underscore respectively. Core is a little outdated and is in need of an update. Yes, there is a core ticket for backbone and underscore on trac but they do need testing.

That’s great!

Now this means I get to set up my test site and try to break things. I’m really looking forward to this part. Yes, I like to figure out where things break and why a lot.

The other reason I’m happy is because earlier today I realized that I didn’t have the WP-API plugin on this site. I know, I know. Core will be using this down the road but this is one thing that really needed to be installed on here for the longest time. I don’t really know how I never installed it long ago but that is now fixed.

I guess the next stage will be in writing out a quick post on my learning of underscore and templating. I did learn a few things while diving into the core files and undercores documentation.

The big lesson learned was that the following code is used in core and can be used in a theme in order to declare your own version of templating rather than having to add wp-util as a dependency.

_.templateSettings = {
		evaluate:    /<#([\s\S]+?)#>/g,
		interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
		escape:      /\{\{([^\}]+?)\}\}(?!\})/g,
		variable:    'data'
	};

Underscore, Backbone, and some basic JavaScript

Themes are awesome. Themes are amazing. Themes should be built with presenting user content in mind.

What happens when you introduce dynamic content? Live content. I know you may be wondering what I mean by this.

A little history

When I first began working with WordPress I knew the basics thing you needed to know about JavaScript. You know, the good old:

document.write( 'Hello world!' );
alert( 'How I am doing?' );
prompt( 'Is this working?' );

Yeah. Super simple things that interact with the browser. Didn’t get too deep into what JavaScript was or how to use it until the last few months. It has always been a goal of mine to learn more things about web development and this year was no different. I grabbed a few JavaScript books and began my quick journey into a world of hurt and a few headaches.

Yes, I got a few headaches and a few nosebleeds because some of the content was far too much to grasp. Some of it I still don’t fully understand but it is slowly making some sense. A lot of what helped was my short lived stint in what will now be a dead language. ActionSript. Yeah. I began that journey because I loved the idea of animating a site with Flash. Sorry. I was young and didn’t really know much better. As I said, this was before I really dove into what JavaScript was capable of doing.

Fast forward a bit and I had begun reading the JavaScript bible seventh edition. Later on I picked up JavaScript in 24 Hours, and a few other code related books. The most recent one being Eloquent JavaScript, Second Edition. I still have some reading to do on that one. I will say though my collection of reading has grown since I first began:

https://www.instagram.com/p/_nOXalML2B

Core usage

Now, as I’ve stated many times on this site, I will always recommend using core first. There are times when you do have to use other tools but that is because you really do have to use the right tool for the right job. When WordPress first introduced two neat little JavaScript libraries I was ecstatic. Backbone and Underscore JS. Both are great little tools that I feel are a great way of creating a theme.

One of the reasons I liked it being integrated was because it can resemble an MVC style of setup. I know there are some people out there who argue against it. I say it resembles in that it uses models and views. It does make it easier for many others to pick up if you come from another content management system other than WordPress. Yes, they do exist.

Yes, my list of reading materials just keeps growing and growing and this does include core code.

What next?

The next step is using all that knowledge and applying it to a theme. Yes, there are sliders out there that use JavaScript but using Backbone and Underscore in a theme would make for a super dynamic experience. Yes, there are other JavaScript libraries that can potentially be used but I’ll stick to learning these first.